Issue with loading/saving an array of structures

Just starting out? Need help? Post your questions and find answers here.
XCoder
User
User
Posts: 68
Joined: Tue Dec 31, 2013 9:18 pm

Issue with loading/saving an array of structures

Post by XCoder »

I created an array with the following structure:

Code: Select all

Structure SQUAREDATA
  SquareNumber.i
  Array InnerSquare.i(8)
  ReadOnly.b
EndStructure

Dim squareData.SQUAREDATA(82)
I run the following program to set up the array with test data and save it to disk:

Code: Select all

Structure SQUAREDATA
  SquareNumber.i
  Array InnerSquare.i(8)
  ReadOnly.b
EndStructure

Dim squareData.SQUAREDATA(82) ;Array range is 0-81

#FileHandle = 0
#SizeOfDataStructure = SizeOf(SQUAREDATA) * 82

Procedure InsertData(Array squareData.SQUAREDATA(1))
For j = 0 To 81
  For k = 0 To 7
    squareData(j)\InnerSquare(k) = j*k
  Next
Next
EndProcedure

Procedure SaveSquareData(Array squareData.SQUAREDATA(1))
  FileNamePath$ = SaveFileRequester("Save test file", "", "Test file *.tst|*.tst", 0)
  Extension$ = GetExtensionPart(FileNamePath$)
  If Extension$ = "" And FileNamePath$<>""
    FileNamePath$ = FileNamePath$ +".tst"
  EndIf
  If FileNamePath$<>""
    If CreateFile(#FileHandle, FileNamePath$)
      WriteData(#FileHandle, @squareData(), #SizeOfDataStructure)
      CloseFile(#FileHandle)
    Else
      MessageRequester("WARNING", "Cannot create this file", #PB_MessageRequester_Warning)
    EndIf
  EndIf
EndProcedure

InsertData(squareData())
SaveSquareData(squareData())

For j = 0 To 81 ;Check the contents of the array
  For k = 0 To 7
    Debug squareData(j)\InnerSquare(k)
  Next
Next
But when I try to load the code with the following program and view the data, I get the error message "Array index out of bounds" when the debug part of the code runs.

Code: Select all

Structure SQUAREDATA
  SquareNumber.i
  Array InnerSquare.i(8)
  ReadOnly.b
EndStructure

Dim squareData.SQUAREDATA(82) ;Array range is 0-81

#FileHandle = 0
#SizeOfDataStructure = SizeOf(SQUAREDATA) * 82

Procedure LoadSquareData(Array squareData.SQUAREDATA(1))
    FileNamePath$ = OpenFileRequester("Open test file", "", "Test file *.tst|*.tst", 0)
    If FileNamePath$<>""
      If OpenFile(#FileHandle,FileNamePath$)
        ReadData(#FileHandle,@squareData(), #SizeOfDataStructure)
        CloseFile(#FileHandle)
        result=#True
      EndIf
    EndIf
  ProcedureReturn result
EndProcedure

LoadSquareData(squareData())

For j = 0 To 81
  For k = 0 To 7
    Debug squareData(j)\InnerSquare(k)
  Next
Next
Can anybody tell me why this happens and how to resolve the issue?

I am using Windows 10 (64k).
User avatar
spikey
Enthusiast
Enthusiast
Posts: 586
Joined: Wed Sep 22, 2010 1:17 pm
Location: United Kingdom

Re: Issue with loading/saving an array of structures

Post by spikey »

"What you get is not actually what you think you're getting" (wyginawytyg never caught on though) ;-)

When you put a dynamically sizeable array into a structure - what actually gets put into the structure is a pointer to the child array. The child array will get its own memory allocation (probably nearby but not sequentially). The compiler knows this though and automatically dereferences the pointers appropriately when a structured object is accessed.

WriteData and ReadData are purely block based and don't understand dereferencing at all. The read back program corrupts the receiving array's pointers with out of date information from the writing program. A failure ensues when the subsequent routine attempts to dereference properly because the layout is now wrong.

What you do about this depends what you are trying to achieve. If your child arrays are always going to be 8 integers then you could use
a static array instead. This does get laid out sequentially and should round trip properly - see below. (Note the revised syntax using [] - your read back program will need to follow suit).

If you need dynamically sized arrays then you could:
  • Roll your own read and write routines and embed the output data with some appropriate sizing data so you can recover the data correctly when you read it back. You'll need to take complete charge of the process though.
  • Use the JSON library which provides some functions to do this sort of thing, if you don't mind your save data becoming JSON.
  • Use the XML library, ditto.

Code: Select all

Structure SQUAREDATA
  SquareNumber.i
  InnerSquare.i[8]
  ReadOnly.b
EndStructure

Dim squareData.SQUAREDATA(82) ;Array range is 0-81

#FileHandle = 0
#SizeOfDataStructure = SizeOf(SQUAREDATA) * 82

Procedure InsertData(Array squareData.SQUAREDATA(1))
For j = 0 To 81
  For k = 0 To 7
    squareData(j)\InnerSquare[k] = j*k
  Next
Next
EndProcedure

Procedure SaveSquareData(Array squareData.SQUAREDATA(1))
  FileNamePath$ = SaveFileRequester("Save test file", "", "Test file *.tst|*.tst", 0)
  Extension$ = GetExtensionPart(FileNamePath$)
  If Extension$ = "" And FileNamePath$<>""
    FileNamePath$ = FileNamePath$ +".tst"
  EndIf
  If FileNamePath$<>""
    If CreateFile(#FileHandle, FileNamePath$)
      WriteData(#FileHandle, @squareData(), #SizeOfDataStructure)
      CloseFile(#FileHandle)
    Else
      MessageRequester("WARNING", "Cannot create this file", #PB_MessageRequester_Warning)
    EndIf
  EndIf
EndProcedure

InsertData(squareData())
SaveSquareData(squareData())

For j = 0 To 81 ;Check the contents of the array
  For k = 0 To 7
    Debug squareData(j)\InnerSquare[k]
  Next
Next
XCoder
User
User
Posts: 68
Joined: Tue Dec 31, 2013 9:18 pm

Re: Issue with loading/saving an array of structures

Post by XCoder »

@spikey: Thanks for your reply. I overlooked the issue of using dynamic arrays - I spent ages trying to resolve this issue. Using a static array will resolve my issue.
User avatar
mk-soft
Always Here
Always Here
Posts: 5393
Joined: Fri May 12, 2006 6:51 pm
Location: Germany

Re: Issue with loading/saving an array of structures

Post by mk-soft »

I like xml for program data and project data

Link: viewtopic.php?f=12&t=74233
My Projects ThreadToGUI / OOP-BaseClass / EventDesigner V3
PB v3.30 / v5.75 - OS Mac Mini OSX 10.xx - VM Window Pro / Linux Ubuntu
Downloads on my Webspace / OneDrive
XCoder
User
User
Posts: 68
Joined: Tue Dec 31, 2013 9:18 pm

Re: Issue with loading/saving an array of structures

Post by XCoder »

Thanks, mk-soft. I will look at the link you provided
Post Reply