Does unique_ptr::release() call the destructor?
C++Unique PtrC++ Problem Overview
Is this code correct?
auto v = make_unique<int>(12);
v.release(); // is this possible?
Is it equivalent to delete
of a raw pointer?
C++ Solutions
Solution 1 - C++
No, the code causes a memory leak. release
is used to release ownership of the managed object without deleting it:
auto v = make_unique<int>(12); // manages the object
int * raw = v.release(); // pointer to no-longer-managed object
delete raw; // needs manual deletion
Don't do this unless you have a good reason to juggle raw memory without a safety net.
To delete the object, use reset
.
auto v = make_unique<int>(12); // manages the object
v.reset(); // delete the object, leaving v empty
Solution 2 - C++
> Is this code correct?
No. Use std::unique_ptr<>::reset()
to delete the internal raw pointer:
auto v = std::make_unique<int>(12);
v.reset(); // deletes the raw pointer
After that is done, std::unique_ptr<>::get()
will return nullptr
(unless you provided a non-nullptr
parameter to std::unique_ptr<>::reset()
).
Solution 3 - C++
> Is this code correct?
It is not, and will leak.
release()
just lets go of the memory ownership that this unique_ptr
held until it was called.
If you don't assign the pointer returned by release()
, you'll just have a leak.
An explicit delete for a unique_ptr
would be reset()
. But do remember that unique_ptr
are there so that you don't have to manage directly the memory they hold. That is, you should know that a unique_ptr
will safely delete its underlying raw pointer once it goes out of scope.
So you should have a very good reason to perform manual memory management on an automatic memory management object.
Solution 4 - C++
release
will leak your raw pointer since you don't assign it to anything.
It is meant to be used for something like
int* x = v.release();
Which means v
is no longer managing the lifetime of that pointer, it is delegating the raw pointer ownership to x
. If you just release
without assigning to anything, you leak the raw pointer.
Solution 5 - C++
it may be a bit tricky for arbitrary types:
unique_ptr<Foo> v = get_me_some_foo(); // manages the object
Foo * raw = v.release(); // pointer to no-longer-managed object
delete raw;
is almost correct.
unique_ptr<Foo> v = get_me_some_foo(); // manages the object
Foo * ptr = v.release(); // pointer to no-longer-managed object
v.get_deleter() ( ptr );
this one would be correct in all situation; there may be a custom deleter defined on type Foo, but using the deleter returned by the unique_ptr object is good for all cases.