From boost documentation on boost::shared_ptr:
Because the implementation uses reference counting, cycles of shared_ptr instances will not be reclaimed. For example, if main() holds a shared_ptr to A, which directly or indirectly holds a shared_ptr back to A, A's use count will be 2. Destruction of the original shared_ptr will leave A dangling with a use count of 1. Use weak_ptr to "break cycles."
I could not understand this paragraph, could you provide a minimum example of this situation and explain the consequence.
How do smart pointer work? They memorize the count
of the smart pointers that point to the object and increase this count
when new shared pointer takes control on the object and decrease the count
if the shared pointer looses control on the object.
Assume you have a class:
class A{
public:
A(){std::cout << "Object created" << std::endl;}
~A(){std::cout << "Object destroyed" << std::endl;}
void setSibling(boost::shared_ptr<A> &sibling){
m_sibling = sibling;
}
private:
boots::shared_ptr<A> m_sibling;
};
and a foo():
void foo(){
//count increases from 0 to 1 (ptr take control on instance of A)
boost::shared_ptr<A> ptr(new A);
//count increases from 1 to 2 (m_sibling take control on instanse of A)
ptr->setSibling(ptr);
//count decreases from 2 to 1
//(ptr is destroyed and lose control on instance of A)
return;
}
The m_sibling will lose control when the ~A() will be called, but ~A() will be called only when all shared pointers will lose a control. So after foo was called you can't access to that instance of A. But the count is 1 and shared pointer will NOT delete that object, so you have memory and resource leak.
See the documentation for weak_ptr
in boost to see how to use them with shared_ptr
.
In short: weak pointer is like shared pointer but do not increase the count
. If you have an instance of weak_ptr created from shared_ptr
to the object that was destroyed, weak_prt instance will throw and exception (segfault won't happen) if you will try to access the raw pointer. There is an example in boost documentation how to use weak_prt
correctly using weak_ptr::lock()
method.