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 if g throws an exception because g() may be called after new int(42) and before the constructor of shared_ptr<int>. This doesn't occur in f(std::make_shared<int>(42), g()), since two function calls are never interleaved.