Is it safe to use
vector.emplace_back( new MyPointer() );
Or could an exception thrown or some failure inside vector cause memory leak?
Would it be better to do some form of the following, where you put the pointer in a temporary unique_ptr first.
vector.emplace_back( std::unique_ptr<MyPointer>( new MyPointer() ) );
So if a vector failure occurs the temporary unique_ptr will still clean up the memory?
It is not safe and would create a memory leak if you use the first version. The documentation says that if an exception is thrown, the call to emplace
has no effect - which means the plain pointer you passed in is never deleted.
You can use
vector.emplace_back( std::unique_ptr<MyPointer>( new MyPointer() ) );
or with C++14 you can use
vector.emplace_back( std::make_unique<MyPointer>() );
or, if C++14 is not yet available, just roll your own version of make_unique
. You can find it here.
No, the first scenario is not safe and will leak memory if the vector
throws an exception.
The second scenario will not compile, as a std::unique_ptr<T>
cannot be implicitly converted to T*
. Even if it could, this scenario is arguably worse than the first, because it will add the pointer to your vector, then immediately delete the object being pointed to. You will be left with a vector containing a dangling pointer.
Without changing the type of your std::vector
(which I assume is std::vector<MyPointer*>
) there are two ways to make this code exception safe.
Using C++11:
auto ptr = std::unique_ptr<MyPointer>(new MyPointer());
vector.emplace_back(ptr.get());
ptr.release();
Or the more verbose C++03 way:
MyPointer* ptr = new MyPointer();
try
{
vector.push_back(ptr);
}
catch (...)
{
delete ptr;
throw;
}
If you are able to change the type of your std::vector<MyPointer*>
then the easiest method are those suggested by Daniel Frey above:
std::vector<std::unique_ptr<MyPointer>> vector;
vector.emplace_back(std::unique_ptr<MyPointer>(new MyPointer()));
Or with C++14:
std::vector<std::unique_ptr<MyPointer>> vector;
vector.emplace_back(std::make_unique<MyPointer>());
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