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、例外がスローされた場合にメモリ リークが発生します。

2 番目のシナリオは、 をstd::unique_ptr<T>暗黙的に に変換できないため、コンパイルされませんT*。できたとしても、このシナリオは最初のシナリオよりも間違いなく悪いです。これは、ポインタをベクトルに追加してから、指しているオブジェクトをすぐに削除するためです。ダングリング ポインターを含むベクトルが残ります。

あなたのタイプを変更せずにstd::vector(私はそれが であると仮定しますstd::vector<MyPointer*>)、このコード例外を安全にする方法が 2 つあります。

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 に答える