On 10/07/13 05:45, Jonathan Wakely wrote:
On 7 October 2013 11:01, Julian Gonggrijp wrote:
The std::weak_ptr detects the dangling pointer and changes it into a null pointer. This makes sense, because null pointers are easier to detect. However, as the surrounding code probably relies on a live pointer (because dangling pointers are never planned) the program is still going to fail. This is what I meant by "disaster".
Why is it going to fail? Expired pointers (not dangling ones) most certainly are planned, and weak_ptr is designed to support (and detect) that case. Users of std::weak_ptr know that it needs to be checked, and the explicit conversion that is needed makes it hard to forget to do that. Either you say:
std::shared_ptr<X> sp(wp);
which will throw if weak_ptr.expired() is true, or you use the non-throwing form in a conditional:
if (auto sp = wp.lock()) /* ... */ ; else /* deal with it */ ;
To provide a concrete example, the attached code produces: ***test_run<1>::run() { obj_id+:10, obj_count:1} { obj_id+:11, obj_count:2} inner empty(wp)=0 inner deref(wp).my_id=11 { obj_id-:11, obj_count:1} exited inner outer empty(wp)=0 outer deref(wp).my_id=0 { obj_id-:10, obj_count:0} exited outer ***test_run<0>::run() { obj_id+:12, obj_count:1} { obj_id+:13, obj_count:2} inner empty(wp)=0 inner deref(wp).my_id=13 { obj_id-:13, obj_count:1} exited inner outer empty(wp)=1 make: *** [run] Segmentation fault (core dumped) where the output prefixed with ***test_run<0>::run used the std:: smart pointers and shows the detection of expired weak_ptr: outer empty(wp)=1 and caused a segfault when it deref'ed the wp. In contrast, the output prefixed with ***test_run<1>::run, which uses the rich_type_ptr smart pointers, does *not* detect the expired weak pointer; consequently, does not cause a segfault when dereferencing that pointer, which, in a real program, would make it harder to find the bug. (BTW, the obj_id.cpp file is found in my other post on a different branch of this thread. ) HTH. -regards, Larry