1

重複の可能性:
ポインタを適切に削除するには?

std::vectorオブジェクトのグループを後で使用するために使用してDETAIL* pPtr = new DETAILいます。ポインターを作成し、それをベクトルに挿入しています。

DETAIL の構造体

struct DETAIL {
    int nRef;
    short sRandom;
};

これは、メモリリークの余地を残さずにベクトル内のポインタを削除および消去する最良の方法ですか?

while(Iter1 != m_Detail.end())
{
    if((*Iter1)->nRef == m_SomeVar)    
    {
        delete  *Iter1;
        m_Detail.erase(Iter1);
        break;
    }

    Iter1++;
}
4

5 に答える 5

9

生のポインタを に置かないでください。vector代わりに、 などのスマート ポインタを使用してくださいstd::shared_ptr。次に、 の必要はありませんdelete。単にeraseからのポインターvectorと、ポイントされたオブジェクトが自動的に削除されます。

于 2012-06-01T18:30:42.507 に答える
0

私の提案は、std :: shared_ptrを使用して、eraseを使用してベクターから共有ポインターを削除し、割り当て解除を処理することです。ただし、実行していることには何の問題もありませんが、消去によって、ベクトルがポインターを保持するために割り当てられたスペースを解放することはありません。shrik_to_fitを使用して、割り当てられたスペースを削除できます。

于 2012-06-01T18:33:17.767 に答える
0

私はDETAIL* pPtr = new DETAILポインタを作成するために使用しています

これが最初の間違いです。リソース (フリーストアからのメモリとそのメモリ内に構築されたオブジェクト) を取得していて、所有権を取得し、取得したリソースの割り当てを解除することを保証するオブジェクトを初期化していません。最初の間違いを解決するイディオムはResource Acquisition Is Initializationと呼ばれます。

次のようになります。

std::shared_ptr<DETAIL> pPtr(new DETAIL);

またはさらに良い:

std::shared_ptr<DETAIL> pPtr = std::make_shared<DETAIL>();

または C++03 ではstd::shared_ptr( boost::shared_ptrand boost::make_shared)に置き換えます。

次の間違いは、デストラクタの外でdelete *Iter1;使用するほとんどすべてのコードdeleteが間違っているためです (そして、デストラクタの外で使用し、メモリ リークを回避する方法に関する質問を伴うすべてのコードdeleteは間違いなく間違っています)。delete適切なタイミングで自動的に行われるため、使用する必要はありません。

また、なぜあなたのクラスは と呼ばれているのDETAILですか? Detail代わりに何が問題なのですか?

于 2012-06-01T20:34:37.437 に答える
0

「決してしない」などの答えは好きではないので答えますが、コンテンツを解放せずにベクトルを解放するリスクを回避するためのいくつかのトリックを提供します。

私がよく理解している場合は、DETAIL ポインターのベクトルがあります。

std::vector<DETAIL*> details;

したがって、特定の m_SomeVar を参照するすべての指定されたオブジェクトを削除および削除するメソッドが必要です: (今のところ、それが無料の関数であると仮定しましょう)

void free_references(int reference, std::vector<DETAIL*> & vector)
{
    std::vector<DETAIL*>::iterator it = vector.begin();

    while (it != vector.end())
    {
        if ((*it)->nRef == reference)
        {
            delete *it;
            // erase() makes the original 'it' in an unknown state which can't be used
            // erase will return a valid iterator which is, in this case, the following element
            it = vector.erase(it); 
        }
        else
        {
            ++it;
        }
    }
}

あなたのコードで理解しているように、ベクトルはクラスのメンバーです。デストラクタ内のすべてを削除できるのは、これが良い理由です。

ただし、std::unique_ptrここでは、ベクトル内の unique_ptr コンテナーへのポインターの所有権を「与える」ために使用します。そして、ベクトル メモリが解放されると、std::unique_ptrスマート ポイントは、所有するポイントされたオブジェクトが解放されることを確認します。

于 2012-06-01T20:47:44.880 に答える
-2

完全に理解したかどうかはわかりませんが、ZeroMemoryマクロを使用してみましたか?

于 2012-06-01T18:32:57.713 に答える