Smart pointers and parameter list allocation rules
If you do this:
func(shared_ptr<Foo>(new Foo), shared_ptr<Bar>(new Bar));
And the signature is:
void func(shared_ptr<Foo>, shared_ptr<Bar>);
What will happen if one of the constructors throws? It may happen that new
has been called once successfully and then the other one fails (you don't know which one will get called first). If that happens, one of the objects could be leaked, because it was never held by a resource manager.
You can read more here: http://www.gotw.ca/gotw/056.htm
It's referring to the possibility of evaluating parameters in a different order, e.g.
func(unique_ptr<MyClass>(new MyClass), a(), b());
if the order of evaluation is: a()
, MyClass()
, b()
, then unique_ptr
is constructed, it might happen that b()
throws and memory will be leaked.
A safeguard (that has been added in C++14 and it's also more efficient) is to use make_unique
(assuming MSVC and according to your compiler version, you might have to define one yourself or take a look here). The same applies to shared_ptr
.
Take a look at the notes for std::make_shared here, too:
Moreover, code such as
f(std::shared_ptr<int>(new int(42)), g())
can cause a memory leak ifg
throws an exception becauseg()
may be called afternew int(42)
and before the constructor ofshared_ptr<int>
. This doesn't occur inf(std::make_shared<int>(42), g())
, since two function calls are never interleaved.