C++11 introduces rvalue references and move semantics, which allow the new smart pointer type
std::unique_ptrthat can be used inside
std::vector. One might have some code like this:
std::vector<std::unique_ptr<Foo>> foos; ... foos.push_back(std::unique_ptr<Foo>(new Foo(...)));
This works just fine, but it's a bit convoluted. Since C++11 introduced both rvalue references and variadic templates,
std::vectorhas a method
emplace_back, which looks more convenient. Let's use it:
std::vector<std::unique_ptr<Foo>> foos; ... foos.emplace_back(new Foo(...));
This works and looks good. However, there is a subtle problem: What happens if the new object of type
Foois constructed, but then the
emplace_backneeds to allocate more memory, and that allocation fails?
The documentation that I can find states that nothing will happen in this case. Does "nothing" mean that we get a memory leak of one Foo object? Apparently it does - and at least a cursory look into the g++ 4.8 STL seems to confirm this suspicion. It appears that this is a potential memory leak that cannot really be avoided in good-looking code.
What to do about this? It would be nice if
emplace_backguaranteed that the desired constructor is called no matter what happens. Unfortunately, such a guarantee would mean constructing the element explicitly in the cleanup path of a
bad_allocexception, which is prone to triggering yet another exception. Seems like this is quite the conundrum...