Boost logo

Boost :

From: Joe Gottman (joegottman_at_[hidden])
Date: 2001-10-19 20:20:37


   I recently had to write a function that took an object of type T* and
returned a boost::shared_ptr<T> *. This was much trickier than it appeared
at first. The first thing I tried was

boost::shared_ptr<T> *createsSharedPtr(T *p)
{
     return new boost::shared_ptr<T>(p);
}

   However, this does not work, and there is no way to use a try-catch block
to make it work. The constructor of smart_ptr<T> tries to construct a new
long for the use count. If this new throws, then the constructor will
delete p and rethrow the exception. However, if the new in my function
throws, then smart_ptr's constructor will never be called, so p will not be
deleted. There is no way to tell a catch() clause which new threw, so it
would be impossible to know whether p still needed to be deleted.

   What I finally ended up doing was :

boost::shared_ptr<T> *createsSharedPtr(T *p)
{
     boost::shared_ptr<T> temp(p);
    return new boost::shared_ptr<T>(temp);
}

If temp's constructor throws, then p will be deleted, otherwise temp is
constructed with a use-count of 1. In the new in the next line throws, then
when temp goes out of scope its use-count will drop to 0 and again p will be
deleted; otherwise shared_ptr's copy constructor will be called. The copy
constructor cannot throw, so temp's use-count will be incremented to 2, and
then go back down to 1 when the function returns, resulting in a new
shared_ptr containing p.

    I think that the documentation of shared_ptr should mention this
problem. It happens whenever an object takes a dynamically created pointer
as a parameter and calls new inside the constructor. There is no way to
safely use such a constructor to create an object on the heap.

Joe Gottman


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