Skip to content


Circular Relationships (VB6)

While I’m thinking about VB6 (not something I’ve done for a while) I remembered another common problem relating to the fact VB is a reference counted language rather than a garbage collected one.

The Problem
For an object to be destroyed it’s reference count must reach zero, this is fine in the majority of cases because VB will happliy clean up references that are no longer in scope. However when a circular reference is created (i.e Parent->Child and Child->Parent) the reference count will never reach 0.

The Common Solution
Ensure all references are released (set to nothing in VB parlance) in the Terminate event of the classes in question. This works fine as long as your development team are incredibly dilligent. Of course in practice what happens is you create memory leaks which take ages to track down.

A Beter Solution
Make the Child->Parent relationship weak (i.e doesn’t increment the reference count on Parent). This can be accomplished with the following code (in a class)

Private Declare Sub CopyMemory Lib “kernel32″ Alias “RtlMoveMemory” (dest As Any, source As Any, ByVal bytes As Long)

Dim m_lParentPtr as Long

Public Property Set Parent(oParent as CParent)

    ’ ObjPtr is an undocumented function
    m_lParentPtr = ObjPtr(oParent)

End Property

Public Property Get Parent as CParent

    Dim oParent As CParent
    ’ Generate an object from the pointer
    CopyMemory oParent, m_lParentPtr, 4
    ’ Return it to the caller
    Set Parent = oParent
    ’ Kill the illegal reference(Your other option is to Increment the reference count on the illegal object to make it legal)
    CopyMemoryAny(WeakRef, 0&, 4&)
End Property

Private Sub IncrementRefCount
    ’ Increments reference counter (simulates IUnkown.AddRef)

    Dim lngRc As Long
    CopyMemory lngRc, ByVal (ObjPtr(Me)) + 4, 4 ‘ Get reference counter value…
    CopyMemory ByVal (ObjPtr(Me)) + 4, (lngRc + 1), 4 ‘ …and increment it

End Sub

Public Function RefCount As Long
    ’ returns the reference counter of obj

    Dim lngRc As Long
    CopyMemory lngRc, ByVal (ObjPtr(Me)) + 4, 4 ‘ Get reference counter…
    RefCount = lngRc – 2

End Function

PS: I haven’t checked this compiles because I don’t have a copy of VB6 handy but the important bits are correct…

Posted in /Technology. Tagged with .

One Response

Stay in touch with the conversation, subscribe to the RSS feed for comments on this post.

  1. There is another way to deal with the circular reference problem that often works: create a new class of objects to hold the information that is common to the parent and children. Give the parent and children a reference to this object. Doesn’t solve every problem but it is fully automatic. See http://en.wikibooks.org/wiki/Programming:Visual_Basic_Classic/Effective_Programming#Avoiding_and_Dealing_with_Circular_References

Some HTML is OK

(required)

(required, but never shared)

or, reply to this post via trackback.