9

使用安全吗

vector.emplace_back( new MyPointer() );

或者向量内部是否会抛出异常或某些故障导致内存泄漏?

执行以下某种形式会更好,首先将指针放在临时的 unique_ptr 中。

vector.emplace_back( std::unique_ptr<MyPointer>( new MyPointer() ) );

因此,如果发生向量故障,临时的 unique_ptr 仍会清理内存吗?

4

2 回答 2

14

如果您使用第一个版本,它不安全并且会造成内存泄漏。文档说,如果抛出异常,则调用emplace无效 - 这意味着您传入的普通指针永远不会被删除。

您可以使用

vector.emplace_back( std::unique_ptr<MyPointer>( new MyPointer() ) );

或使用 C++14,您可以使用

vector.emplace_back( std::make_unique<MyPointer>() );

或者,如果 C++14 尚不可用,只需推出您自己的make_unique. 你可以在这里找到它。

于 2013-10-16T21:38:08.673 回答
4

不,第一种情况是不安全的,如果vector抛出异常会泄漏内存。

第二种情况不会编译,因为 astd::unique_ptr<T>不能隐式转换为T*. 即使可以,这种情况也可能比第一种情况更糟,因为它会将指针添加到您的向量,然后立即删除指向的对象。您将得到一个包含悬空指针的向量。

在不改变你的类型std::vector(我假设是std::vector<MyPointer*>)的情况下,有两种方法可以使这个代码异常安全。

使用 C++11:

auto ptr = std::unique_ptr<MyPointer>(new MyPointer());
vector.emplace_back(ptr.get());
ptr.release();

或者更详细的 C++03 方式:

MyPointer* ptr = new MyPointer();
try
{
  vector.push_back(ptr);
}
catch (...)
{
  delete ptr;
  throw;
}

如果您能够更改您的类型,std::vector<MyPointer*>那么最简单的方法是上面 Daniel Frey 建议的方法:

std::vector<std::unique_ptr<MyPointer>> vector;
vector.emplace_back(std::unique_ptr<MyPointer>(new MyPointer()));

或者使用 C++14:

std::vector<std::unique_ptr<MyPointer>> vector;
vector.emplace_back(std::make_unique<MyPointer>()); 
于 2013-10-17T01:40:50.713 回答