views:

11

answers:

1

Hi unfortunately I'm not so good in the whole garbage collection thing. Now I am unsure if I'm going to get into trouble if I'm doing the following:

// unmanaged Class
class CUnmagedClass : public CCmdTarget
{
    auto_gcroot<Dictionary<int, System::String^>^> m_dict;
    auto_gcroot<SomeManagedClass^> m_managedClass;

    // create first manage object in one gcroot
    CUnmagedClass()
    :dict(gcnew Dictionary<LANGID, System::String^>())
    {}

    // do something with the dictionary
    void AddData(int key, String^ value)
    {
         this->m_dict->Add(key, value);
    }

    // Method that could be called multiple times
    void DoOtherThings(Data^ data)
    {
         // create a new object on every method call
         // old object can be garbage collected
         this->m_managedClass = gcnew SomeManagedClass(data);
         // assign a reference to the dictionary from the other gcroot
         this->m_managedClass->DictProp = this->m_dict;

         this->m_managedClass->DoSomething();
    }

}

So my question is, if I overwrite the value in this->m_managedClass and the older SomeManagedClass instance is garbage collected. Does the system try to collect the object in this->m_managedClass->DictProp too because it's not connected to the second gcroot anymore or is the garbage collector clever enough to know that there is a reference left in the other gcroot?

A: 

The system will not try to collect this->m_managedClass->DictProp too because it is clever enough to know that this object is referenced by the other gcroot.

The reason the gcroot is this clever is that it wraps System::Runtime::InteropServices::GCHandle, which is a handle into the garbage collected heap. The GCHandle class is what allows your unmanaged object to store what is effectively a managed reference. Also, even if your managed object is moved by the garbage collector, the GCHandle reference will be updated to point to its new location.

mcdave