How Does Use Of Make_unique Prevent Memory-leak, In C++?
fn(unique_ptr<A>{new A{}},unique_ptr<B>{new B{}});
is troublesome as A
or B
gets leaked if an exception is thrown there.
fn(make_unique<A>(),make_unique<B>());
on the other hand is considered exception-safe.
Question:
Why? How does use of make_unique prevent memory-leak?
What does make_unique do that the defaultunique_ptr does not?
Kindly help me out, please.
Thank you.
Answer
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.
Related Questions
- → Comparing two large files are taking over four hours
- → Setting JSON node name to variable value
- → Compiling GLUT using Emscripten
- → Evaluate check box from a scanned image in node.js
- → Find an easy web server framework for mobile game
- → my https C++ code doesn't work on some sites (binance)
- → Error while opening pivx wallet on ubuntu
- → Why sending a POST by AJAX is interpreted by the HTTP Server as OPTIONS and sending by CURL is effectively a PUT?
- → Python reading in one line multiple types for a calculator
- → How do I properly pass an argument to a function
- → Accessing Websql database with Qt
- → Using Mysql C API for c++ codes
- → How do I set constants at run-time in a c++ header file, imported through Cython?