Boost logo

Boost :

From: Darin Adler (darin_at_[hidden])
Date: 2001-10-18 02:24:22


on 10/17/01 10:50 PM, Greg Colvin at gcolvin_at_[hidden] wrote:

> If this is a bug the fix below looks OK to me. Does anyone see
> a problem? Can someone volunteer to make the patch in CVS?

The patch looks good to me, too. And I think the bug report is correct; it's
good to have a version of shared_ptr that can deal with the fact that
deleting the pointed to object might delete the shared_ptr itself. But I
have a slight refinement to the fix.

Here's my version:

   void reset(T* p=0) {
      if (px == p) return; // fix: self-assignment safe
      if (*pn == 1) {
        T* old_px = px;
        px = p;
        checked_delete(old_px);
      }
      else { // allocate new reference counter
        long* old_pn = pn;
        scoped_ptr<T> sp(p);
        pn = new long(1); // may throw
        --*old_pn;
        px = sp.release();
      } // allocate new reference counter
   } // reset

> operator=(const shared_ptr&) and
> operator=(std::auto_ptr&) have the same problem and fix
> is very similiar.

For operator=(const shared_ptr&), I found it was much easier (and about as
efficient) to use the copy and swap idiom rather than trying to fix the hole
by further complicating the share function.

   shared_ptr& operator=(const shared_ptr& r) {
      shared_ptr copy(r);
      swap(copy);
      return *this;
   }

For operator=(const auto_ptr&), I think it's best to leverage the reset
call, already written correctly.

   template<typename Y>
      shared_ptr& operator=(std::auto_ptr<Y>& r) { reset(r.release()); }

If these changes look OK to you, I'll be happy to do the fix in cvs after
some further testing.

    -- Darin


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk