Difference between revisions of "HOWTO resolve circular references in ns-3 memory disposal"

From Nsnam
Jump to: navigation, search
(HOWTO resolve smart pointer circular references in ns-3 memory disposal)
(HOWTO resolve smart pointer circular references in ns-3 memory disposal)
Line 60: Line 60:
 
     ==16877==    possibly lost: 0 bytes in 0 blocks
 
     ==16877==    possibly lost: 0 bytes in 0 blocks
  
Note for many ns
+
An explicit call to Dispose() is not always necessary.  Before the simulator exits, Dispose() is called on all ns-3 nodes.  Therefore if your object is aggregated onto a node or aggregated onto something that is aggregated onto a node etc., explicitly calling Dispose is not necessary.
 +
 
 +
For example:
 +
    <pre>
 +
    int main(int argc, char* argv[])
 +
    {
 +
        Ptr<A> a = CreateObject<A>();
 +
        Ptr<B> b = CreateObject<B>();
 +
        Ptr<Node> node = CreateObject<Node>();
 +
        a->m_callback = MakeCallback (&B::CallbackMethodB, b);
 +
        b->AggregateObject(a);
 +
        node->AggregateObject(b);
 +
    }
 +
    </pre>
 +
 
 +
An explicit call to Dispose is not necessary here.
 +
 
 +
    ==17541== LEAK SUMMARY:
 +
    ==17541==    definitely lost: 0 bytes in 0 blocks
 +
    ==17541==    indirectly lost: 0 bytes in 0 blocks
 +
    ==17541==    possibly lost: 0 bytes in 0 blocks

Revision as of 18:20, 30 August 2013

HOWTO resolve smart pointer circular references in ns-3 memory disposal

    class A : public Object
    {
    public:
       static TypeId GetTypeId (void);
       Callback<void> m_callback;
    };
    class B : public Object
    {
    public:
       static TypeId GetTypeId (void);
       void CallbackMethodB (void);
    };
     int main(int argc, char* argv[])
     {
        Ptr<A> a = CreateObject<A>();
        Ptr<B> b = CreateObject<B>();
        a->m_callback = MakeCallback (&B::CallbackMethodB, b);
        b->AggregateObject(a);
     }
     
    ==15749== LEAK SUMMARY:
    ==15749==    definitely lost: 40 bytes in 1 blocks
    ==15749==    indirectly lost: 152 bytes in 5 blocks
    ==15749==    possibly lost: 0 bytes in 0 blocks

The preferred way to break reference cycles like this in ns-3 is to use Object::Dispose(). This method will call the DoDispose method on the object that it is called on as well as all other objects aggregated on to it. In the above example Class A is aggregated to Class B so we make the following change to Class A:

    class A : public Object
    {
    public:
       static TypeId GetTypeId (void);
       Callback<void> m_callback;
       virtual void DoDispose (void)
       {
          m_callback = MakeNullCallback<void>();
       }	
    };

Now the following code:

     int main(int argc, char* argv[])
     {
        Ptr<A> a = CreateObject<A>();
        Ptr<B> b = CreateObject<B>();
        a->m_callback = MakeCallback (&B::CallbackMethodB, b);
        b->AggregateObject(a);
        b->Dispose(); 
        //a->Dispose() will work as well.  Both will end up calling DoDispose 
        //in object 'a' which breaks the reference cycle	
     }
     

will no longer have a memory leak.

    ==16877== LEAK SUMMARY:
    ==16877==    definitely lost: 0 bytes in 0 blocks
    ==16877==    indirectly lost: 0 bytes in 0 blocks
    ==16877==    possibly lost: 0 bytes in 0 blocks

An explicit call to Dispose() is not always necessary. Before the simulator exits, Dispose() is called on all ns-3 nodes. Therefore if your object is aggregated onto a node or aggregated onto something that is aggregated onto a node etc., explicitly calling Dispose is not necessary.

For example:

     int main(int argc, char* argv[])
     {
        Ptr<A> a = CreateObject<A>();
        Ptr<B> b = CreateObject<B>();
        Ptr<Node> node = CreateObject<Node>();
        a->m_callback = MakeCallback (&B::CallbackMethodB, b);
        b->AggregateObject(a);
        node->AggregateObject(b);
     }
     

An explicit call to Dispose is not necessary here.

    ==17541== LEAK SUMMARY:
    ==17541==    definitely lost: 0 bytes in 0 blocks
    ==17541==    indirectly lost: 0 bytes in 0 blocks
    ==17541==    possibly lost: 0 bytes in 0 blocks