|
Boost : |
From: Borgerding, Mark A. (MarkAB_at_[hidden])
Date: 2000-03-03 16:52:22
> -----Original Message-----
> From: Jens Maurer [mailto:jmaurer_at_[hidden]]
> Sent: Friday, March 03, 2000 4:25 PM
> To: boost_at_[hidden]
> Subject: [boost] Re: shared_ptr co-existence with other smart pointers
...
>
> But, there are shared pointer variants such as linked_ptr<>
> which can inform all other instances that the underlying
> object is no longer managed by this linked_ptr<> cooperative.
> With these, it would be safe to call release(), because
> no other linked_ptr<> will try to delete the data storage,
> and accesses will try to dereference a NULL pointer, with the
> usual implementation-defined *bang*.
I though of several approaches to release().
Approach #1)
Notify everybody.
In this approach, every linked_ptr to a given heap object would be
nullified. The problem with this is that it could have unexpected results
in other threads.
void foobar(linked_ptr<foo> spFoo)
{
if (spFoo.get())
{
// spFoo is not null, we checked.
// Suppose the time slice is interrupted here
// and spFoo is nullified.
//
spFoo->bar(); // BOOM!
}
}
Conclusion:
- Indirect results possible
- Prone to difficult-to-find errors
Approach #2)
"I got mine. Don't worry 'bout his."
In this approach, a linked_ptr would mark the heap object as non-destroyable
and nullify itself. All connected linked_ptrs would still have the ptr, but
would know not to delete it.
Conclusion:
- dangling pointers likely
- Prone to difficult-to-find errors
Aprroach #3)
release only if unique() is true
This is the approach currently defined in linked_ptr:
// element_type * release ()
// Effects:
// If unique() returns true: the previous value of get() is returned
and
// the user claims responsibility for deletion.
// If unique returns false: the previous value of get() will be
deleted
// by other linked_ptr objects and 0 is returned.
// Postcondition: get() thereafter returns 0
element_type * release() {
element_type * origPtr = 0;
if ( unique() ) {
origPtr = ptr;
ptr = 0;// just give it up without deletion
}else
reset(0);// take *this out of list, leaving
// responsibility for deletion to other nodes
return origPtr;// null if not unique
}
By using the return code of release to find out if the object was the last
reference, a user can avoid dangling pointers.
Conclusion:
-Slight bias toward double-deletion, which makes it
-Slightly prone to easy-to-find errors
All things considered, the conditional release may be a little less
powerful, but it is a lot more stable and predicatble than the other
approaches.
- Mark
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk