6

このコードが複数のメモリリークを引き起こすのか、それとも正しくクリーンアップされるのか、私はただ興味がありました。

Node *newNode;

for (int i = 0; i < 10; i++)
{
    newNode = new Node();
}

delete newNode;

したがって、明らかにコードは何もしませんが、私のシナリオを説明するのに役立ちます。メモリを10回割り当てていますか?ポインタを削除すると、9つの孤立が残りますか?または、割り当てられている同じスペースを再利用して、孤立したスペースを正しく削除していますか?前もって感謝します!

4

2 に答える 2

7

ええ、これはメモリリークです。あなたがするとき:

newNode = new Node();

新しく割り当てられたメモリを指すようにポインタを再定義しているため、実際には、以前にポイントされていたメモリを削除するためにアドレス指定する方法がわかりません。

したがって、ループを終了すると、newNodeポインタは最後に割り当てられた(10番目の)メモリ/を指しますNodedelete newNodeそのメモリのみを削除する場合。あなたはもはやdelete他の人に行く方法がありません。

Zhi Wangが指摘したように、何らかの形式のスマートポインター(またはC ++ 11など)を使用できunique_ptrますshared_ptr。これらのスマートポインターは基本的に、この種のリークを防ぐ追加のセマンティクスを持つ通常のポインターのラッパーです。これらのいずれかを使用した場合、メモリ/オブジェクトは、スコープ外になると(forその場合はループの現在の反復が終了すると)、自動的に割り当てが解除されます。

ただし、この場合、これで状況が解決するとは思いません。delete10個のオブジェクトを作成したらすぐに作成したいとは思わない。むしろ、これらのオブジェクトをのようなコンテナに格納するstd::vectorか、少なくともこれらの割り当てられたインスタンスのそれぞれを指すポインタの配列を用意する必要があります。そうすれば、オブジェクトを周囲に配置し(オブジェクトを構築しているので、これが必要なものであると私は信じています)、後でオブジェクトを削除する方法もあります。

于 2013-03-14T03:39:00.027 に答える
5

はい、コードはメモリリークを起こします。動作に関する最初の推測は正しいです。このコード

Node *newNode;

for (int i = 0; i < 10; i++)
{
    newNode = new Node();  // allocate memory 10 times in a loop...
}

delete newNode;            // ... but free the memory only once!

メモリを10回割り当てます(ループnew内の演算子)が、それらのオブジェクトの1つ(下部の演算子)forのみが使用するメモリを解放します。当然、これにより他の9つのオブジェクトは孤立したままになります。それらが消費するメモリは引き続き割り当てられますが、アクセスして解放する方法はありません。つまり、もちろん、メモリリークの定義そのものです。delete

対照的に、このコード

Node *newNode;

for (int i = 0; i < 10; i++)
{
    newNode = new Node();    // allocate memory 10 times in a loop
    delete newNode;          // ... and free the memory each time
}

deleteへの呼び出しごとに1つの呼び出しがあるため、メモリをリークしませんnew。これは、覚えておく必要のある大きなルールです。への各呼び出しをnew、への対応する呼び出しと一致させないdeleteと、メモリリークが発生します。

または、C ++で作業している場合のさらに良いルールは、そもそも生のポインターを使用しないことです。C ++標準ライブラリは、ポインタのRAIIイディオムを実装する、いくつかの優れたラッパークラスを提供します。これにより、ポイントされたオブジェクトが適切に破棄され、それらが消費するメモリが解放されます。お気に入りのC++ブック、またはWikipediaで調査を開始します。

于 2013-03-14T03:47:09.523 に答える