How does use of make_unique prevent memory-leak, in C++?
std::make_unique
doesn't "prevent" memory-leak in the sense that it's still possible to write memory leaks in programs that use std::make_unique
.
What does std::make_unique
is make it easier to write programs that don't have memory leaks.
A or B gets leaked if an exception is thrown there.
Why?
Pre C++17:
Because if you allocate A
, then call constructor of B
before constructing the std::unique_ptr
that was supposed to own A
, and the constructor of B
throws, then A
will leak (or same happens with A
and B
reversed).
Since C++17:
There's no leak since the scenario described above cannot happen anymore in the shown example.
What does make_unique do that the default unique_ptr does not?
std::make_unique
allocates memory, and either successfully returns a valid std::unique_ptr
, or throws an exception without leaking memory.
std::unique_ptr(T*)
accepts a pointer that was allocated separately. If an exception is thrown before the constructor is called, then there will never have been a unique pointer owning the allocation.
It's possible to fix the (pre-C++17) bug without using std::make_unique
:
auto a = std::unique_ptr<A>{new A{}};
auto b = std::unique_ptr<B>{new B{}};
fn(std::move(a), std::move(b));
But if you always use std::make_unique
, then you won't accidentally make the mistake of writing leaky version. Furthermore, std::make_unique
lets you avoid writing new
which allows you to use the rule of thumb "write exactly one delete for each new". 0 new -> 0 delete.