Page 1 of 1

[5.22 beta 1] InitializeStructure() memory leak

Posted: Wed Mar 05, 2014 3:21 pm
by NicTheQuick
If you call 'InitializeStructure()' two times in a row it also allocates memory two times without freeing the memory used before.

I assume this behaviour because I get no error if I initialize the structure with some random data. It would be great if 'InitializeStructure()' only initializes dynamical objects which were not initialized before.
The other solution for me is if 'ClearStructure()' would only deinitialize the dynamic objects without clearing all other "normal" members of the structure. Maybe with an optional parameter?

Code: Select all

Structure test
	List a.i()
EndStructure

*a.test = AllocateMemory(SizeOf(test))

;Poke some invalid pointer into the address
PokeI(*a, 1234)
Debug PeekI(*a)

;No error because of wrong pointer
InitializeStructure(*a, test)
Debug PeekI(*a)

;test\a gets a new pointer
InitializeStructure(*a, test)
Debug PeekI(*a)
Background information: I want to be able to do this:

Code: Select all

Structure test
	*vTable
	List a.i()
EndStructure

Structure test2 Extends test
	member.i
EndStructure

*a.test = AllocateMemory(SizeOf(test2))

InitializeStructure(*a, test)
*a\vTable = 123

ClearStructure(*a, test)
*b.test2 = *a
InitializeStructure(*a, test2)
*b\member = 456

Debug *b\vTable
Debug *b\member

Re: [5.22 beta 1] InitializeStructure() memory leak

Posted: Wed Mar 05, 2014 5:19 pm
by luis
NicTheQuick wrote: [5.22 beta 1] InitializeStructure() memory leak

If you call 'InitializeStructure()' two times in a row it also allocates memory two times without freeing the memory used before. It would be great if 'InitializeStructure()' only initializes dynamical objects which were not initialized before.
Uhmmm... but in this case this is a feature request, not a bug report.
help wrote: Warning: multiple calls to InitializeStructure create a memory leak because the old members are not freed (ClearStructure has to be called before calling InitializeStructure once more).


It would be great if 'InitializeStructure()' only initializes dynamical objects which were not initialized before.
I don't see this as being much different from repeatedly calling AllocateMemory() using the same pointer:

Code: Select all

*p = AllocateMemory(1024) ; memory leak
*p = AllocateMemory(2048) ; memory leak 
*p = AllocateMemory(4096)
FreeMemory(*p)
The right thing to do is to not call InitializeStructure() repeatedly on the same address, like you do not calling AllocateMemory() repeatedly using the same pointer.

Use FreeMemory() between two AllocateMemory() and use ClearStructure() between two InitializeStructure(), why change this ? It's clear and coherent.

NicTheQuick wrote: The other solution for me is if 'ClearStructure()' would only deinitialize the dynamic objects without clearing all other "normal" members of the structure.


Background information: I want to be able to do this:

Code: Select all

Structure test
	*vTable
	List a.i()
EndStructure

Structure test2 Extends test
	member.i
EndStructure

*a.test = AllocateMemory(SizeOf(test2))

InitializeStructure(*a, test)
*a\vTable = 123

ClearStructure(*a, test)
*b.test2 = *a
InitializeStructure(*a, test2)
*b\member = 456

Debug *b\vTable
Debug *b\member
You want to keep vTable and at the same time re-initialize the dynamic list in the structure ?
If that's what you want you can do it this way:

Code: Select all

Structure test
   *vTable
   List a.i()
EndStructure

Structure test2 Extends test
   member.i
EndStructure

*a.test = AllocateMemory(SizeOf(test2))

InitializeStructure(*a, test)
*a\vTable = 123

FreeList(*a\a())
*b.test2 = *a

InitializeStructure(*a, test2)
*b\member = 456

Debug *b\vTable
Debug *b\member
help wrote: InitializeStructure initialize the specified structured memory area. It initializes structure members of type Array, List and Map, other members are not affected (.s, .l, .i etc).

Re: [5.22 beta 1] InitializeStructure() memory leak

Posted: Mon Mar 10, 2014 12:51 pm
by Fred
BTW, the clear is not done automatically, because we don't assume than the new memory area is filled with zeros. If you use AllocateMemory() with the #PB_Memory_NoClear flag, you can still call InitializeStructure() right after. If we called ClearStructure here, it will crash if some memory fields are array, list or map as the pointers will be garbage.