Subject: Re: [boost] [smart_ptr] Interest in the missing smart pointer (that can target the stack)
From: Gavin Lambert (gavinl_at_[hidden])
Date: 2016-02-01 20:21:19
On 29/01/2016 23:25, Andrey Semashev wrote:
> I think what Emil describes is a special case of a 'dangling_ptr' idiom,
> if I may call it that way. The point is that there are cases when object
> lifetime is controlled by a third party (e.g. the stack state, a foreign
> library, etc.) and you need a safe way to know when the object has been
> deleted. So you create a shared_ptr with a null_deleter pointing to that
> object and save it in that object (or another storage associated with
> that object). You keep only weak_ptrs to that object in all other places
> in the code. When you need to use the object you have to lock a weak_ptr
> and thus check if the object is still alive.
The thing is that there is rarely a case in practice where doing this is
actually beneficial, unless you have a bit of code that *usually* deals
with "real" shared_ptrs in the full shared-ownership sense and you want
to exercise them in a context where you know they won't be used
concurrently -- eg. unit tests.
Typically single-threaded algorithms have a well-defined point at which
the object is deleted (if this is a possibility), so it's not necessary
to track this separately, and raw pointers/references are sufficient.
(And if you're religiously opposed to having raw owning pointers, then
use unique_ptr for the owning pointer and references for everything else.)
We've already established that making a copy of the shared_ptr to be
used outside the call chain (eg. by another thread, or just by this
thread in a later operation) is obviously unsafe.
Storing a weak_ptr in the single-threaded case is safe but pointless, as
it should be obvious whether the object is alive or not during the
initial operation (the code that deletes it can just store back a NULL,
after all), and it will be guaranteed to be dead after that operation
anyway. (This does assume that you have a known place to go to find
that weak_ptr, rather than having lots of copies of it.)
Storing a weak_ptr in the multi-threaded case is unsafe, because such
code expects to be able to promote one to a shared_ptr during some
operation and for the underlying object to not be deleted while that
operation is in progress, the latter of which is violated when the
lifetime is not controlled by the shared_ptr itself.
It's that second aspect of weak_ptr -- the ability to promote to a
shared_ptr and carry out operations secure in the knowledge that the
object won't be surprise-deleted under you by concurrent action -- that
many people seem to forget when discussions of wanting to use weak_ptr
without shared ownership come up.
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk