On 11.6.2012 19:47, Travis Gockel wrote:
The copy constructor for weak_ptr constructs px like so:
px(r.lock().get())
Why do it this way and not just:
px(r.px)
This introduces a somewhat unexpected race in that the shared_ptr obtained with lock() can be the last outstanding shared_ptr and the object can be destroyed during this copy. It is certainly not a /bug/ in the smart_ptr library, but the behavior is unexpected and quite inconvenient. I assume there is a reason for calling lock() and not just copying the pointer and I would like to know what it is.
This is actually commented in smart_ptr/weak_ptr.hpp (just above the first px(r.lock().get()) construction thing): // // The "obvious" converting constructor implementation: // // template<class Y> // weak_ptr(weak_ptr<Y> const & r): px(r.px), pn(r.pn) // never throws // { // } // // has a serious problem. // // r.px may already have been invalidated. The px(r.px) // conversion may require access to *r.px (virtual inheritance). // // It is not possible to avoid spurious access violations since // in multithreaded programs r.px may be invalidated at any point. // -- Pekka