std::vector
生のポインターを保存するときに例外セーフではなく、代わりにunique_ptr
orを使用する必要があると何度か言及されていると聞きましたshared_ptr
。
私の質問は、なぜstd::vector
例外セーフではないのか、これらのクラスはそれをどのように修正するのかということです。
std::vector
例外が安全ではないということではなく、メモリ管理に生のポインターを使用しています。
int main()
{
try
{
int* i = new int;
throw "oops, memory leak!";
}
catch (...){}
}
これはベクター自体とは何の関係もありません。これを行うことはまったく同じ問題です。
int main()
{
try
{
std::vector<int*> vi;
vi.push_back(new int);
throw "oops, memory leak!";
}
catch (...){}
}
これらは両方とも、スマート ポインターを使用して修正されます。
int main()
{
try
{
std::unique_ptr<int> i(new int);
std::vector<std::unique_ptr<int>> vi;
vi.push_back(std::unique_ptr<int>(new int));
vi.push_back(std::move(i));
throw "vector destroys unique_ptr's...which delete their memory";
}
catch (...){}
}
(またはshared_ptr
、より高価です。Boost のポインター コンテナーを使用することもできます。)
「例外セーフではない」とは、例外中の巻き戻しによってベクトルが破壊された場合にメモリリークが発生することを意味していると思います。
Shared_ptr は、ベクトル自体が破棄されたときに、ポインターが指すオブジェクトが確実に削除されるようにします。
もう 1 つの代替手段は、Boost ポインター コンテナーです。