I've narrowed the code down to a small sample. It seems to occur with structure items that include strings.
Here's the sample code:
Code: Select all
#MaxItems = 7
Structure item
enum.s ;Either "0" or "1"
EndStructure
Structure itemCollection
Size.i ;zero based count of items present
items.item[#MaxItems]
EndStructure
Procedure randomFill(*collection.itemCollection)
;fill the first 7 items of collection with either a "1" or "0"
Protected i, enum.s
*collection\Size = #MaxItems - 1
For i = 0 To *collection\Size
If Random(1)
enum = "1"
Else
enum = "0"
EndIf
*collection\items[i]\enum = enum
Next
EndProcedure
Procedure.s showit(*collection.itemCollection)
;return a string containing the contents of collection in a comma delimeted list
Protected i, output$
For i = 0 To *collection\Size
output$ + Chr(34) + *collection\items[i]\enum + Chr(34)
If i <> *collection\Size: output$ + ", ": EndIf
Next
ProcedureReturn output$
EndProcedure
;This procedure seems to be malfunctioning (notice all the debugs ;) )
;It mangles the contents of the collection on occasion.
Procedure removeOnes(*collection.itemCollection)
;remove all ones in collection
Debug "": Debug "begin removal of 1's"
Protected i, operation.s
Debug " " + showit(*collection)
For i = *collection\Size To 0 Step -1
If *collection\items[i]\enum = "1"
Debug " Clearing item #" + Str(i)
ClearStructure(@*collection\items[i], item) ; has a problem here
Debug " clear struc " + showit(*collection)
If i < *collection\Size
MoveMemory(@*collection\items[i + 1], @*collection\items[i], SizeOf(item) * (*collection\Size - i)) ;no problems here
operation = " move data "
Else
operation = " adjust size "
EndIf
*collection\Size - 1
Debug operation + showit(*collection)
EndIf
Next
EndProcedure
Define a.itemCollection, i
RandomSeed(12) ;for results that are reproducable
For i = 0 To 100
randomFill(a)
removeOnes(a)
Next
The removing occurs in the procedure removeOnes(). This procedure clears the structure of matching items and then either overwrites them with the remaining items using movememory() or adjusts the count of items if it is the last item being removed.
Occasionally ClearStructure() produces odd and soon to be fatal results, especially when items are being removed from the end of the collection. In many cases if there are multiple items the same it will remove all of them in one swoop (without being told to do so).
Can anyone offer an explanation or point out where the program logic is flawed? I don't need a way to accomplish the task another way (thanks anyway

@Edit: it appears the problem is with a duplication of a structure(s) as a side-effect of the use of MoveMemory(). Added [Solved] to title.