What happens when an exception is thrown in std::vector<>::emplace_back()
?
For example:
class Foo {
public:
Foo(int bar) {
if (bar == 4) throw std::exception("Something went wrong");
}
}
and
std::vector<std::unique_ptr<Foo>> foo_list;
foo_list.emplace_back(new Foo(3));
try {
foo_list.emplace_back(new Foo(4));
} catch (std::exception error) {
// How bad is it?
}
// Whats inside foo_list now?
I would expect the vector to just contain the first Foo object.
Is this the case? And is this guaranteed by the standard?
And also: Could there be any memory leaks?
I would expect the vector to just contain the first Foo object.
Is this the case? And is this guaranteed by the standard?
Yes. The comments above already explained that emplace_back
never even gets called because the Foo
constructor throws while initializing the arguments for the function.
But ...
And also: Could there be any memory leaks?
Yes, you are using the anti-pattern that I have described at Inserting into a container of smart pointers with emplace_back(new X) (also published in Overload Journal #134 - August 2016).
The problem happens when emplace_back
needs to reallocate the vector and that fails due to running out of memory. The pointer passed into the function will be lost, and so you leak the Foo
object. This can happen for the first insertion (where the Foo
constructor doesn't throw):
foo_list.emplace_back(new Foo(3));
Never use emplace_back
to insert raw pointers into a container of unique_ptr
, instead use make_unique
:
foo_list.emplace_back(std::make_unique<Foo>(3));
Or if you have to use C++11 then construct the unique_ptr
and insert or emplace that, not a raw pointer:
foo_list.emplace_back(std::unique_ptr<Foo>(new Foo(3)));
This way the object is owned by a unique_ptr
immediately, and so if an exception happens inside emplace_back
the object will be destroyed correctly.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With