Main advantage of shared_ptr is that it automatically releases the associated memory when not used any more.

But if we don’t use shared_ptr carefully then this advantage can turn into a disadvantage. Let’s look how,

Suppose I have to design a binary tree and in it the node contains a pointer to left and right children.

bst

In above example, everything goes fine i.e.

3 times constructor will called and then 3 times destructor,

it means complete memory is deleted.

But if we add an another small requirement i.e. each node will contain a pointer to parent’s node. Then it will cause problem with shared_ptr.


Checkout modified example,

Now constructor will be called 3 times but there will be no call to destructor and that is a memory leak.

Reason of this problem with shared_ptr is cyclic references i.e.

If two objects refer to each other using shared_ptrs, then no one will delete the internal memory when they goes out of scope.

It happens because shared_ptr in its destructor after decrementing the reference count of associated memory checks if count is 0 then it deletes that memory and if it’s greater than 1 then it means that any other shared_ptr is using this memory.

But in this kind of scenario these shared_ptrs will always found count greater than 0 in destructor.

Let’s reconfirm this for above example,

When ptr’s destructor is called,

o    It decrements the reference count by 1.

o    Then checks if current count is 0 but that is 2 because both left and right child has a shared_ptr object referencing to parent i.e. ptr.

o    Left and Right Child will be deleted only when memory for ptr will be deleted but that’s not going to happen because reference count is greater than 0.

o    Hence memory for neither ptr nor its children will be deleted. Therefore no destructor was called.

Now How to fix this problem?

Answer is using weak_ptr.

Weak_ptr allows sharing but not owning an object. It’s object is created by a shared_ptr.

With weak_ptr object we cannot directly use operators * and -> to access the associated memory. First we have to create a shared_ptr through weak_ptr object by calling its lock() function,  then only we can use it.

Check below example,

Important Point: lock() can return empty shared_ptr if that shared_ptr us already deleted.

Improving our Binary tree example with weak_ptr

In case of cyclic references i.e. two objects refer to each other using shared_ptrs, change one object to contain weak_ptr instead of shared_ptr.

Hence by using weak_ptr the memory leak problem is solved for binary tree nodes.

Join LinkedIn Group of Python Professional Developers who wish to expand their network and share ideas.

You can also follow us On Twitter :

Click Here to Subscribe for more Articles / Tutorials like this.