Possible Duplicate:
How to release pointer from boost::shared_ptr?
A function of my interface returns a pointer to an object. The user is supposed to take ownership of that object. I do not want to return a Boost.shared_ptr, because I do not want to force clients to use boost. Internally however, I would like to store the pointer in a shared_ptr to prevent memory leaks in case of exceptions etc. There seems to be no way to detach a pointer from a shared pointer. Any ideas here?
After you initialize a shared_ptr you can copy it, pass it by value in function arguments, and assign it to other shared_ptr instances.
A null shared_ptr does serve the same purpose as a raw null pointer. It might indicate the non-availability of data. However, for the most part, there is no reason for a null shared_ptr to possess a control block or a managed nullptr .
When you copy a std::shared_ptr in a thread, all is fine. At first to (2). By using copy construction for the std::shared_ptr localPtr, only the control block is used. That is thread-safe.
std::shared_ptr::getReturns the stored pointer. The stored pointer points to the object the shared_ptr object dereferences to, which is generally the same as its owned pointer.
What you're looking for is a release
function; shared_ptr
doesn't have a release function. Per the Boost manual:
Q. Why doesn't shared_ptr provide a release() function?
A. shared_ptr cannot give away ownership unless it's unique() because the other copy will still destroy the object.
Consider:
shared_ptr<int> a(new int); shared_ptr<int> b(a); // a.use_count() == b.use_count() == 2 int * p = a.release(); // Who owns p now? b will still call delete on it in its destructor.
Furthermore, the pointer returned by release() would be difficult to deallocate reliably, as the source shared_ptr could have been created with a custom deleter.
Two options you might consider:
std::tr1::shared_ptr
, which would require your users to use a C++ library implementation supporting TR1 or to use Boost; at least this would give them the option between the two.boost::shared_ptr
-like shared pointer and use that on your external interfaces.You might also look at the discussion at this question about using boost::shared_ptr in a library's public interface.
there's always a way :-)
There is indeed a reason why they don't provide a release() method, but it's not impossible to create one. Make your own deleter. Something on the line of (haven't actually compiled the code, but this is the general notion):
template <typename T> class release_deleter{ public: release_deleter() : released_(new some_atomic_bool(false)){} void release() {released_->set(true);} void operator()(T* ptr){if(!released_->get()) delete ptr;} private: shared_ptr<some_atomic_bool> released_; } .. shared_ptr<some_type> ptr(new some_type, release_deleter<some_type>()); .. release_deleter<some_type>* deleter = get_deleter<release_deleter<some_type>>(ptr); deleter->release(); some_type* released_ptr = ptr.get();
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With