Does memory get freed when reassigning std::unique_ptr?

Viewed 898

Given the following:

{
    std::unique_ptr<char[]> foo;
    foo = std::make_unique<char[]>(100);
    foo = std::make_unique<char[]>(200);
}

Does the memory allocated in the first call to make_unique get freed when reassigning foo with the second call?

3 Answers

There is no leak in this code. operator= for std::unique_ptr will call the Deleter (in this example, delete[]) for the existing memory when transferring ownership from another unique_ptr that is being assigned to it.

Per cppreference:

std::unique_ptr<T,Deleter>::operator=

Transfers ownership from r to *this as if by calling reset(r.release()) followed by an assignment of get_deleter() from std::forward<E>(r.get_deleter()).

std::unique_ptr<T,Deleter>::reset

Given current_ptr, the pointer that was managed by *this, performs the following actions, in this order:

  • Saves a copy of the current pointer old_ptr = current_ptr
  • Overwrites the current pointer with the argument current_ptr = ptr
  • If the old pointer was non-empty, deletes the previously managed object
    if(old_ptr) get_deleter()(old_ptr)

You only define foo once.
Specifically, in the first line in the scope:

std::unique_ptr<char[]> foo;

As it is default-initialized, the default-ctor is called, which initializes with nullptr.

The other two lines assign a new value to foo, no re-definition which would be an error.

And yes, if you assign a new value to foo, the assignment-operator will free the previously owned memory, guaranteed.

Yes, unique_ptr has an array specialization which will call the array-wide destructor when the unique_ptr goes out of scope:

https://en.cppreference.com/w/cpp/memory/unique_ptr

As you can see in the last example, where it creates an array of Ds, then calls the destructor for all the Ds that were created.

Related