hm.. Well, Tinman, I believe I've found your original
post, however it seems that this 'nasty hack' as you put it may not work anymore :/ At least.. when I tried it with this example code, it shows that somewhere around 0 memory is being freed:
Code: Select all
;manual structure memory allocation/memory leak test #3
Structure STR
StructureUnion
String.s
Pointer.l
EndStructureUnion
EndStructure
Structure mystruct
st1.s
st2.s
st3.s
st4.s
st5.s
st6.s
st7.s
st8.s
st9.s
st10.s
EndStructure
Procedure debugmemory ()
Static lastval
memstat.MemoryStatus
GlobalMemoryStatus_(memstat)
newval = memstat\dwAvailPhys
diff = newval - lastval
lastval = newval
ProcedureReturn diff
EndProcedure
Procedure FreeString(*free_me.STR)
! MOV edx, dword [esp+0]
! MOV edx, dword [edx]
! CALL SYS_FreeString
*free_me\Pointer = 0
EndProcedure
Debug "Initial Memory free: " + Str(debugmemory ())
*eh.mystruct
*eh = AllocateMemory (SizeOf (mystruct))
*eh\st1 = Space (60000)
*eh\st2 = Space (60000)
*eh\st3 = Space (60000)
*eh\st4 = Space (60000)
*eh\st5 = Space (60000)
*eh\st6 = Space (60000)
*eh\st7 = Space (60000)
*eh\st8 = Space (60000)
*eh\st9 = Space (60000)
*eh\st10 = Space (60000)
Debug "Memory difference after allocating 10 strings of 60,000 bytes: " + Str(debugmemory ())
FreeString(@*eh\st1)
FreeString(@*eh\st2)
FreeString(@*eh\st3)
FreeString(@*eh\st4)
FreeString(@*eh\st5)
FreeString(@*eh\st6)
FreeString(@*eh\st7)
FreeString(@*eh\st8)
FreeString(@*eh\st9)
FreeString(@*eh\st10)
FreeMemory(*eh)
Debug "Memory reclaimed by freeing strings and de-allocating structure: " + Str(debugmemory ())
I had to rename the "STRING" structure from your example to "STR", as it seems "STRING" is already defined. Anyhow, fortunately it seems that the latest PB update's bug fix to do with strings in structures in linked lists, is perfectly relevant, as this code seems to prove:
Code: Select all
;manual structure memory allocation/memory leak test #2
;allocate structure using PB's linked list instead of AllocateMemory
Structure mystruct
st1.s
st2.s
st3.s
st4.s
st5.s
st6.s
st7.s
st8.s
st9.s
st10.s
EndStructure
Procedure debugmemory ()
Static lastval
memstat.MemoryStatus
GlobalMemoryStatus_(memstat)
newval = memstat\dwAvailPhys
diff = newval - lastval
lastval = newval
ProcedureReturn diff
EndProcedure
NewList list.mystruct()
AddElement (list())
Debug "Initial Memory free: " + Str(debugmemory ())
*eh.mystruct
*eh = list()
*eh\st1 = Space (60000)
*eh\st2 = Space (60000)
*eh\st3 = Space (60000)
*eh\st4 = Space (60000)
*eh\st5 = Space (60000)
*eh\st6 = Space (60000)
*eh\st7 = Space (60000)
*eh\st8 = Space (60000)
*eh\st9 = Space (60000)
*eh\st10 = Space (60000)
Debug "Memory difference after allocating 10 strings of 60,000 bytes: " + Str(debugmemory ())
DeleteElement(list())
Debug "Memory reclaimed by freeing strings and de-allocating structure: " + Str(debugmemory ())
It seems my best bet will be to just use PB's linked lists, and design around the inherant flaws they present.
Thank you very much for your help though tinman

I really have to learn ASM sometime so I can take advantage of it in languages such as PB which allow you to inline it.. and, well, naturally your code brings a few more questions to mind..! It would indeed be useful for other purposes to be able to manually free a string, so I would like to see if it's possible to get this hack working.
Code: Select all
Procedure FreeString(*free_me.STR)
! MOV edx, dword [esp+0]
! MOV edx, dword [edx]
! CALL SYS_FreeString
*free_me\Pointer = 0
EndProcedure
I can sort of see what the code is trying to accomplish, except I'm a little confused at how it seems you are writing a variable to the edx register, only to overwrite it in the next instruction with it's own contents? Or is EDX used to store the parameter for the SYS_FreeString call? (which is indeed what is perhaps failing) Also.. why would you write [esp+0].. isn't that the same as just [esp]?
Would you mind taking the time to explain what this code is doing?
