Safe to use vector.emplace_back( new MyPointer ); Could failure inside vector lead to leaked memory?

有些话、适合烂在心里 提交于 2019-12-05 20:07:58

问题


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?


回答1:


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.




回答2:


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>()); 


来源:https://stackoverflow.com/questions/19414331/safe-to-use-vector-emplace-back-new-mypointer-could-failure-inside-vector-le

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!