A colleague at work was recently tasked with refactoring some legacy code and came across the good old

std::auto_ptr
. In C++0x it has been deprecated (and later removed outright; I can’t even compile
std::auto_ptr
code in Visual Studio 2017 nor Xcode 10.1) so it was his job to rewrite it in the modern C++ way. The code that my colleague came across had another problem. Can you spot it?

std::auto_ptr p1(new T[3]);

std::auto_ptr
was never meant to hold pointers to arrays. So the code above, assuming it didn’t crash, was leaking memory (regardless of what it holds,
std::auto_ptr
always calls
delete
in its destructor;
delete[]
was needed in the code above).

So how do we refactor legacy

std::auto_ptr
code into modern C++? The answer is
std::unique_ptr
(https://en.cppreference.com/w/cpp/memory/unique_ptr). A
std::auto_ptr
holding a pointer to a single object of type
T
, in modern C++, becomes:

auto p2 = std::make_unique();

std::make_unique
can forward constructor parameters to
T::T
, like this:

auto p3 = std::make_unique("string parameter");

And an array of

T
‘s of size
N
becomes:

auto p4 = std::make_unique(N);

Note that for

std::make_unique
to be able to create an array of
T
‘s,
T
must have a
T::T()
(default constructor; or a constructor with all parameters having default values:
T::T(int x = 0)
).

One Reply to “Refactoring std::auto_ptr”

  1. Should we use container or std::array for dynamic array ? I think it’s better than warping pointer to an array with smart pointer . 🙂

Leave a Reply