Does unique_ptr::release() call the destructor?

C++Unique Ptr

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

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionZeukisView Question on Stackoverflow
Solution 1 - C++Mike SeymourView Answer on Stackoverflow
Solution 2 - C++Johann GerellView Answer on Stackoverflow
Solution 3 - C++JBLView Answer on Stackoverflow
Solution 4 - C++Cory KramerView Answer on Stackoverflow
Solution 5 - C++MichaelMoserView Answer on Stackoverflow