[SmartPointers] weak_ptrs, raw pointers, and cycles
I've recently realized that I just don't get something. Cycles of shared_ptrs are bad, because they can lead to resource leaks. To break a cycle, we're encouraged to use weak_ptrs. Okay, but we could use raw pointers to break the cycle, too, and I can't see any advantage offered by the weak_ptr. If A uses a shared_ptr to B and B uses a weak_ptr to A, B's life will be shorter than A's (its destructor will be invoked from A's destructor and will run to completion before A's does), so there is no advantage to a weak_ptr being able to tell if it dangles. In this context, it never will. So it seems that using a raw pointer to break cycles has no disadvantage over a weak_ptr, and it's more efficient (i.e., smaller and faster). Clearly, I'm missing something. Can somebody please explain what it is? I understand that weak_ptrs have other uses (e.g., as observers), so my question is only about the advice to use weak_ptrs to break cycles. Thanks, Scott
What if something else has a shared_ptr to B? -----Original Message----- From: Scott Meyers [mailto:usenet@aristeia.com] Sent: Friday, August 18, 2006 10:05 AM To: boost-users@lists.boost.org Subject: [Boost-users] [SmartPointers] weak_ptrs, raw pointers, and cycles I've recently realized that I just don't get something. Cycles of shared_ptrs are bad, because they can lead to resource leaks. To break a cycle, we're encouraged to use weak_ptrs. Okay, but we could use raw pointers to break the cycle, too, and I can't see any advantage offered by the weak_ptr. If A uses a shared_ptr to B and B uses a weak_ptr to A, B's life will be shorter than A's (its destructor will be invoked from A's destructor and will run to completion before A's does), so there is no advantage to a weak_ptr being able to tell if it dangles. In this context, it never will. So it seems that using a raw pointer to break cycles has no disadvantage over a weak_ptr, and it's more efficient (i.e., smaller and faster). Clearly, I'm missing something. Can somebody please explain what it is? I understand that weak_ptrs have other uses (e.g., as observers), so my question is only about the advice to use weak_ptrs to break cycles. Thanks, Scott _______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
Michael Nicolella wrote:
What if something else has a shared_ptr to B?
Yes, this is what I was missing, thank you very much. (Embarrassingly, I'd drawn a picture of this exact situation so I'd remember why the weak_ptr was useful, then I found that I didn't understand my own picture. Sigh.) Thanks all for the instant clarification. Scott
Hi all, New user of boost so I'd like to get some advice and make sure that I'm going down the right road. Currently, I've rolled my own DFS but it's buggy and hard to use so I'm thinking about switching to boost. Here's a picture of what I have. http://img.photobucket.com/albums/v642/rssmps/Untitled-1.jpg Initially, I have all the vertex and edges in a bucket. My task is using all the vertex/edge available and discover the connection that they belong to and then produce a connection summary. In words: 1) between 2 vertex, there can be multiple edges. In the end, I'll need to know what all of them are. However, I'm thinking it can be simplified during graph traversal to just using one edge. Once path is known, I can assign the remaining edges to the right connection. 2) undirected. However, edge definition in cases where multiedges exists maybe mixed. So one edge may be from A->B while another edge between A & B maybe defined as B->A. 3) need to handle a connection that has multiple inlet/outlet/cycle 4) As seen from the picture. The vertex/edge do not all belong to one big graph but rather a series of non-connected graphs. My current code works for all the straight forward connections but the one with the cycle is where I'm having trouble with. So is connected components the right tool to use? Thanks!
Sorry about the unrealated topic! I thought I was starting a new thread. Not sure how it ended up as a reply.
I think it's probably OK to break the cycle with a raw pointer (unless I am missing something), as long as you're sure that nothing else can have a shared_ptr to that B object (because then the B object isn't guaranteed to be destroyed in that particular A's destructor, and then the ptr back to A could be dangling). But if A is supposed to completely control B's lifetime like that, why are we using a shared_ptr at all? Maybe auto_ptr or scoped_ptr is a better choice? -----Original Message----- From: Scott Meyers [mailto:usenet@aristeia.com] Sent: Friday, August 18, 2006 10:05 AM To: boost-users@lists.boost.org Subject: [Boost-users] [SmartPointers] weak_ptrs, raw pointers, and cycles I've recently realized that I just don't get something. Cycles of shared_ptrs are bad, because they can lead to resource leaks. To break a cycle, we're encouraged to use weak_ptrs. Okay, but we could use raw pointers to break the cycle, too, and I can't see any advantage offered by the weak_ptr. If A uses a shared_ptr to B and B uses a weak_ptr to A, B's life will be shorter than A's (its destructor will be invoked from A's destructor and will run to completion before A's does), so there is no advantage to a weak_ptr being able to tell if it dangles. In this context, it never will. So it seems that using a raw pointer to break cycles has no disadvantage over a weak_ptr, and it's more efficient (i.e., smaller and faster). Clearly, I'm missing something. Can somebody please explain what it is? I understand that weak_ptrs have other uses (e.g., as observers), so my question is only about the advice to use weak_ptrs to break cycles. Thanks, Scott _______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
On 8/18/06, Scott Meyers
... If A uses a shared_ptr to B and B uses a weak_ptr to A, B's life will be shorter than A's (its destructor will be invoked from A's destructor and will run to completion before A's does), so there is no advantage to a weak_ptr being able to tell if it dangles.
I may also be missing some context here, however I think the fact that we're using a shared_ptr to B (instead of a scoped_ptr) indicates that we're not guaranteed to be the only ones w/ a shared_ptr to B, in which case we can't guarantee that B's life will be shorter than A's. Jon
Scott, In the described case I would bet, that the weak pointer is never reset to NULL, since you copy pointer and not pointer by reference or pointer to pointer.... So if you are going to check if weak pointer is valid, it will be always valid, since copied by value nothing will reset it to NULL. weak_ptr has for example bool expired()const member function, but I think it could also be an operator bool()const function which reports the pointer validity. So the first issue would be the checking of pointer validity. On the other hand you can produce a valid shared_ptr out of weak_ptr, by calling the lock member, since weak_ptr shares the reference counter with shared_ptr but does not increase it. Even if you are in a cycle, some call to a data structure member might wish to ensure, that an object which is pointed to by weak_ptr will not expire until the call is finished. So this call should call weak_ptr::lock member and receive for the scope of call valid shared_ptr. With Kind Regards, Ovanes Markarian On Fri, August 18, 2006 19:04, Scott Meyers wrote:
I've recently realized that I just don't get something. Cycles of shared_ptrs are bad, because they can lead to resource leaks. To break a cycle, we're encouraged to use weak_ptrs. Okay, but we could use raw pointers to break the cycle, too, and I can't see any advantage offered by the weak_ptr. If A uses a shared_ptr to B and B uses a weak_ptr to A, B's life will be shorter than A's (its destructor will be invoked from A's destructor and will run to completion before A's does), so there is no advantage to a weak_ptr being able to tell if it dangles. In this context, it never will. So it seems that using a raw pointer to break cycles has no disadvantage over a weak_ptr, and it's more efficient (i.e., smaller and faster). Clearly, I'm missing something. Can somebody please explain what it is?
I understand that weak_ptrs have other uses (e.g., as observers), so my question is only about the advice to use weak_ptrs to break cycles.
Thanks,
Scott
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
participants (6)
-
Andrew Ferng
-
Ferng, Andrew D
-
Jonathan Franklin
-
Michael Nicolella
-
Ovanes Markarian
-
Scott Meyers