1. ホーム
  2. c++

[解決済み] なぜC++の「ベクター」で新規呼び出しをするのか?

2022-03-03 12:21:50

質問

コード vector<someType> myVector; は動的にメモリを確保するため、保存された要素は delete が呼び出されます。では、次のような場合はどうでしょう。 vector<someType> *myVector = new vector<someType>(); は、先ほどのものと(ポインタであること以外)違うのでしょうか?

ここで二重のアロケーションが起こっているのでしょうか? 誰もが vectornew の呼び出しがありますが、なぜでしょうか?もし邪道なら、なぜコンパイラにとって許容できるコードで、いつ使ってもいいのでしょうか?

どのように解決するのか?

最初の記述は正しくありません。の要素は vector<someType> myVector は、ベクターが破壊されるまで生き続けます。もし vector<someType> がローカル変数である場合、スコープ外に出たときに自動的に破棄されます。明示的にdeleteを呼び出す必要はない。呼び出し方 delete 例外がスローされる可能性があることを考慮すると、明示的に行うことはエラーの原因になります。 delete 文にたどり着けず、メモリリークにつながる可能性があります。 例えば、次の2つのケースを比べてみてください。

void foo()
{
   std::vector<int> v;
   v.push_back(1);
   f(); // f is some operation that might throw exception.
}  // v is automatically destroyed even if f throws.

void bar()
{
   std::vector<int>* v = new std::vector<int>;
   v->push_back(1);
   f(); // f is some operation that might throw exception.
   delete v;  // You need to call delete explicitly here.
              // The vector will be destroyed only if f doesn't throw.
}

上記とは別に、ベクターが新しい要素を格納するために動的にメモリを確保することは事実です。この2つの場合の違いは

  • std::vector<int> v vはスタック上のオブジェクトで、要素を格納するために動的にメモリを確保する。

  • std::vector<int>* v = new std::vector<int> v は動的に割り当てられたオブジェクトへのポインターで、要素を格納するために動的にメモリが割り当てられます。すでに述べたように、このオブジェクトを破棄するには明示的にdeleteを呼び出す必要があります。