4

整数を(オブジェクトの)ベクトルに関連付けるマップがあります。これらのベクトルは、実行する一連のタスクを表します。このマップとベクトルを使用しているときに発生するコピーの量を減らすために、ポインターを使用するように設定しました。

std::map<int, std::vector<MyObject *> *> myMap;

myMapを保持するクラスの初期化中に、新しいMyObjectsで満たされた新しいベクトルを作成してmyMapにデータを入力します。

しかし、私が懸念しているのはメモリ管理です。今、私はこれらのさまざまなオブジェクトをヒープのどこかに置いてあり、それらを使い終わったらそれらをクリーンアップする責任があります。私はまた、プログラムが終了するまで、私は決して彼らと一緒に終わらないことを知っています。しかし、誰かがこのアプリを変更する賢い方法が地図/ベクトルからアイテムを削除することを含むと決定したとき、10週間でどうでしょうか。これにより、メモリリークが発生します。

私の質問は、これらのオブジェクトの適切な割り当て解除を処理して、STL関数を介してオブジェクトが削除された場合でも、オブジェクトの割り当てが正常に解除されるようにするにはどうすればよいですか?

あなたの助けは大歓迎です、私が何か重要なものを逃したかどうか私に知らせてください!ありがとう!

4

6 に答える 6

8

生のポインタではなく、スマートポインタboost:shared_ptrを使用します。そうすれば、オブジェクトが破棄されたときに、ヒープに割り当てられたメモリもクリアされます。

boost :: shared_ptr http://www.boost.org/doc/libs/1_39_0/libs/smart_ptr/shared_ptr.htm

また、ベクトルへのポインタを持つ理由は本当にありますか?それらはほとんどスペースを占有せず、std :: map内のオブジェクトはとにかく移動されません(たとえば、より多くのスペースを取得するために、ベクトルが再割り当てされるたびに移動/コピーされるベクトル内のオブジェクトとは異なります)。

編集:また、shared_ptrはtr1のコンポーネントであり、次の標準に含まれていると確信しているので、コンパイラーにはすでに含まれている可能性があります。他にもたくさんのスマートポインタがあり、STLで安全に自分で書く方法を知ることができます。グーグルですばやく検索すると、それらが見つかるはずです。

EDIT2:チェックしたところ、TR1のVisual Studio 2008実装には、Visual C ++ 2008FeaturePackに含まれているshared_ptrが含まれています。他の多くのベンダーがTR1の少なくとも一部で利用可能な実装を持っていると思います。したがって、VSを使用していない場合は、ベンダーのサイトでTR1サポートを検索してください。

于 2009-07-20T11:42:47.803 に答える
5

スマートポインタを使用するのが良い方法であることに同意しますが、少なくとも2つの選択肢があります。

a)コピーはあなたが思っているほど高価ではないかもしれません。値のマップを実装してみてください

std::map<int, std::vector<MyObject>> myMap;

b)ベクトルを、ベクトルをラップする独自のクラスに置き換えます。そのクラスのデストラクタで、割り当て解除を処理します。MyObjectsを追加および削除するためのメソッドを提供することもできます。

于 2009-07-20T12:00:48.797 に答える
1

(他の人が提案しているように)共有ポインタを使用するのが最善の解決策です。

あなたがそれらを決して終わらせないことを本当に知っているなら、それらは技術的に割り当てを解除する必要はありません。これが本当に望ましい動作である場合は、10週間以内に誰かが来ないように文書化し、これを本物のリークと間違えます。

于 2009-07-20T11:48:51.270 に答える
1

良い答えをありがとうございました。私は現在、値のベクトルソリューションに傾いていると思います。主な理由は、std :: auto_ptrはコピーできないため、コレクションでは機能しないことです。これは、面倒な審査プロセスを経たり、自分でロールしたりすることなく使用できるスマートポインターの唯一の実装です。

良いニュースは、あなたの回答が私を非常に良い道に導いたことです。RAII、例外処理の危険性、およびそれらを最小限に抑える方法について学び、その「正しさ」に満足できるように十分な注意を払って設計しました。

添付されているのは、途中で役立つと思ったリンクです。同様の問題が発生した場合は、これらのリンクがお役に立てば幸いです。


C++のRAIIリソーススマートポインター
Boostスマートポインタースマートポインター
に関する背景/実装の詳細

于 2009-07-22T11:43:16.733 に答える
0

使用時にコピーを最小限に抑える方法について詳しく説明しmap<,vector<Object>>ます。

mapとのインターフェースをよく見てくださいvector。それらは主に含まれているアイテムへの参照を返します、そしてあなたがこれらのものを渡す際に参照を保存するならば、コピーは起こりません。

悪い例:

std::vector<MyObject> find_objects( const std::map<int,std::vector<MyObject>> & map, int i ) {
    const std::map<int,std::vector<MyObject>>::const_iterator it = map.find( i );
    if ( it != map.end() )
        return it->second;
    else
        return std::vector<MyObject>();
}
// ...
const std::vector<MyObject> objects = find_objects(/*...*/);

より良い:

const std::vector<MyObject> & find_objects( const std::map<int,std::vector<MyObject>> & map, int i ) {
    const std::map<int,std::vector<MyObject>>::const_iterator it = map.find( i );
    if ( it != map.end() )
        return it->second;
    static const std::vector<MyObject> none();
    return none;
}
// ...
const std::vector<MyObject> & objects = find_objects(/*...*/);

->コピーなし

于 2009-07-22T17:34:34.433 に答える
0

各ポインターの所有権がベクター/マップ内の異なるエントリ間で共有されていないため、挿入時に実行されるコピーを減らすことだけを意味する場合は、boostのポインターコンテナーライブラリも検討する必要があります。

于 2009-07-20T22:40:44.973 に答える