OK, hope the topic title isn't too confusing. Let me explain by code.
'The test type
Type TA
'Data member
Field child:TB
Global counter:Int
Method New()
TA.counter:+1
End Method
Method Delete()
TA.counter:-1
End Method
End Type
'Type that contains a reference to it's parent
Type TB
Field m_main:TA
Method SetMain(main:TA)
Self.m_main = main
End Method
End Type
'Test function
Function Test(set_main:Int = False)
Local obj:TA = New TA
obj.child = New TB
'Make a reference is set_main = True
If set_main = True
obj.child.SetMain(obj)
End If
'Enable this line to fix the problem
'But shouldn't deleting the parent object
'already have to do this?
'obj.child = Null
'Destroy object
obj = Null
'Force garbage collection for instantly deleting objects
GCCollect()
End Function
'----------------------------
Test()
'Should print 1
Print TA.counter
'----------------------------
Test(True)
'Should print 1 because the data member did not contain a reference
Print TA.counter
'----------------------------
'I expect it to print 1, but it does print 2
'The data member contains a reference to the parent
'But since the parent has been nullified I expect
'it to get cleared as well
Test(True)
Print TA.counter
'----------------------------
'Prints 3. But if the last result would've printed 1
'then this would also result in 1
Test()
Print TA.counter
So in short, you have an object that has a data member which in turn keeps a reference to its parent. I noticed that when setting the reference in the child data member and then deleting the parent doesn't destroy the objects.
Is this supposed to happen? The reference counters for both the parent and child should be set to 0 after killing the parent wouldn't it? Because what's happening now is memory leakage.
Is my understanding of the garbage collector wrong or is this a bug? If this is intended behavior then how can I work around this issue? When Nullifying the child first and then the parent does seem to fix it. But what if you have a whole lot more data members? Shouldn't nullifying the parent have to do this?
I'm using BlitzMax 1.30 by the way.
|