Boost logo

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!

        - 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.

        - 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
   // the user claims responsibility for deletion.
   // If unique returns false: the previous value of get() will be
   // 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
         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.

        -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

- Mark

Boost list run by bdawes at, gregod at, cpdaniel at, john at