Is it true that unique_ptr which points to an array will automatically free dynamic memory after calling release()?
I looked a little in this, and I'm guessing this was just a mistake on the author's part. cppreference.com makes no reference to any array specialization for release
. Just to make sure, I went ahead and checked the source code for libc++ (LLVM's implementation of the standard library). This is the implementation for std::unique_ptr<T[], Deleter>::release
. As you can see, it does not call delete[]
. My guess is the author meant to write up.reset();
, as this does free the memory.
// up points to an array of ten uninitialized ints unique_ptr<int[]> up(new int[10]); up.release(); // automatically uses delete[] to destroy its pointer
This is incorrect. up.release()
is not calling delete[]
for the array it manages. It is simply releasing ownership of the array and returning a pointer to it. It is, therefore, the responsibility of the coder to call delete[]
.
I think you are getting mixed up with std::unique_ptr<T, Deleter>::reset()
which does free the allocated memory.
Demo:
#include <iostream>
#include <memory>
class Test
{
public:
Test() { std::cout << "Test()" << std::endl; }
~Test() { std::cout << "~Test()" << std::endl; }
};
int main()
{
std::unique_ptr<Test[]> up(new Test[3]);
auto ptr = up.release();
return 0;
}
Output:
Test()
Test()
Test()
The destructor is not called. So we have a memory leak! The only way to avoid this is to call delete[] ptr;
after auto ptr = up.release();
Note: from C++14 onward you can write:
std::unique_ptr<CTest[]> up = std::make_unique<CTest[]>(3);
This is better than explicitly new-ing because it will not leak if an exception is thrown.