2

そこで、ここでいくつかのメモリ管理手法を実装しようとしています。私のプログラムでは、stlリストを作成して、クラス「Blast」のオブジェクトとそれぞれのイテレータが含まれるようにしました。

list<Blast> blasts;
list<Blast>::iterator it1;

調べてみると、erase関数を使用すると、クラスのデストラクタが呼び出され、オブジェクトを指すイテレータが削除され、他のポインタ(イテレータ)が返されることがわかりました。ただし、クラスがPODの場合、デストラクタの呼び出しは何も実行しないため、そのオブジェクトに保存されたすべての情報はメモリに保持されます。

これを回避するために、オブジェクトを動的に割り当てて、削除関数を使用してオブジェクトをメモリから消去できるようにしました。

Blast *blast;
blast = new Blast;

しかし、ここで問題が発生しました。オブジェクトをリストにプッシュしようとすると、ポインターをプッシュすることしかできません。

blasts.push_back(*blast);

最初は何も考えていませんでした。だから私は続けた:

if(it2->getX() > 600) {

   delete &it2;
   it2 = blasts.erase(it2);

   }

そのとき、これが行うことは、オブジェクトを指しているポインターを消去し、次にオブジェクトを指しているポインターを指しているポインターを消去することであることに気付きました。

メモリリークがあるかどうかを知る方法がないため、それが実際に正しいかどうかは完全にはわかりません。だから私の質問はこれです:

そのオブジェクトを指しているポインタを削除する前に、メモリからオブジェクトを消去するにはどうすればよいですか?私の実装は正しいですか?オブジェクトをリストにプッシュするだけの場合と同じ結果になりますか?

4

1 に答える 1

1

次に、オブジェクトを指すイテレータを削除し、他のポインタ(イテレータ)を返します。

ポインタではなく、イテレータです。

したがって、そのオブジェクトに保存されたすべての情報はメモリに保持されます。

いいえ、そうではありません。

オブジェクトをリストにプッシュしようとすると、ポインターをプッシュすることしかできません。

は?あなたがその時を持っているなら、もちろんあなたはリストにstd::list<Blast>保存することができません、それは同じタイプではありません。Blast*たぶんあなたはリストを?に変更したいstd::list<Blast*>ですか?

delete &it2;

これは間違っています。参照しているリスト要素ではなく、イテレータを削除しようとします。必要な要素を削除するには、次のようにします。

delete &*it2;

しかし、それでもまだある場合はstd::list<Blast>、リストが所有するオブジェクトを削除しようとします。これは非常に間違っており、バグの原因になります。

この質問全体に固執して忘れるべきだと思います。std::list<Blast>要素を消去してもオブジェクトが破壊されないという誤解に基づいているようですが、これは真実ではありません。問題がBlast動的に割り当てられたメモリを指すポインタメンバーをオブジェクトに持っていることである場合は、デストラクタを追加しBlastて適切にクリーンアップします。

于 2012-10-14T23:46:25.320 に答える