4

私の単純なゲームエンジンには、エンティティへのポインタを含むベクトルがあります。各エンティティには、新しいキーワードが割り当てられます。エンティティの関数を呼び出すためにイテレータを使用しているので、エンティティを削除するときに、次のようにイテレータも使用すると考えました。

vector<Entity*>::iterator iter;
for (iter = gameEntitys.begin(); iter != gameEntitys.end();) {
    delete (*iter);
    ++iter;
}

しかし、私は今、恐ろしいメモリリークを抱えており、すべてのプロファイリングツールがラインを指していますdelete (*iter);

明らかに何か問題がありますが、ベクトルに含まれているエンティティを削除する(そして別のシーンのベクトルをクリアする)ための正しい方法は何ですか。使用gameEntitys.clear();することは、実際のデータではなくポインタであるため、実際にはdeleteを呼び出さないベクトルの要素を削除するだけなので、私の知る限りでは役に立ちません。

編集:私はコメントを見ている蜂を持っています。Entityクラスはポリモーフィックではなく、サブクラスもありません。動的メモリの使用をやめ、非ポインタエンティティの通常の配列があった場合、より意味がありますか?

メモリリークがあることを私が知っている理由は、アプリケーションが起動すると、クラッシュする前にメモリ使用量が最大2GBを超えるためです。

4

1 に答える 1

7

ほとんどの場合、メモリリークは、またはそのサブクラスの1つのデストラクタから発生してEntityいます。delete操作を正しく実行しているため、デストラクタ自体に障害がある必要があります。一般的な問題の1つは、ポリモーフィッククラス階層でデストラクタを仮想化しないことです。

あなたはまた、呼び出すことの無用さについても絶対に正しいですgameEntitys.clear():それはそれらへの参照を「忘れる」ことによってあなたのオブジェクトを「卸売り」するでしょう。

C ++ 11を使用している場合は、使用する定義を変更することを検討してくださいstd::unique_ptr

std::vector<std::unique_ptr<Entity> > gameEntitys;

これにより、エントリのメモリを手動で管理する必要がなくなり、派生クラスのオブジェクトへのポインタをで保持できるようになりますvector。を使用する場合unique_ptr、toを呼び出すとgameEntitys.clear()、ベクトルの要素が指すアイテムが破棄されます。

のベクトルのunique_ptr処理は多少異なりますが(たとえば、新しいアイテムを挿入するには特別な注意が必要です。詳細については、この回答を参照してください)、単純化されたメモリ管理の利点は、わずかな不便を補うと思います。

編集:Entityクラスはポリモーフィックではないため、後でポリモーフィック階層に切り替える予定がない限り、に切り替えることを検討しstd::vector<Entity>てください。

于 2012-10-01T17:07:28.393 に答える