0

メモリリークが発生しないことを確認したい。

   struct tStruct{
       uint32_t id;
       A* a;
       C b;
   };
   std::vector<tStruct*> m_vector;

次の方法でオブジェクトをベクトルにプッシュして消去します。

押す:

tStruct* myStruct = new tStruct;
myStruct->id = ID; // Some unique value
myStruct->a= new A();
myStruct->b = c; // c is an object
m_vector.push_back(myStruct);

消去:

 // Some stuff here 
 for (uint32_t i = 0; i < m_vector.size(); i++) {
     if (m_vector.at(i)->id == ID) { // Some filtering
         delete m_vector.at(i);
         m_vector.erase(m_vector.begin() + i);
     }
 }

私はそれを正しく理解していますか

  1. ヒープに割り当てられているため、明示的に myStruct->a を削除する必要がありますか?
  2. 他のメンバーについては、スタックにあるため、自動的に削除されます。
4

4 に答える 4

2

経験則: がある場合newは、対応する が必要deleteです。C の malloc と free と同じです。

于 2013-01-30T09:41:51.030 に答える
1

によって作成され、動的に割り当てられたすべてのオブジェクトを手動で削除する必要がありますnew operator。そうしないと、削除していないため、メモリリークが発生する可能性がありますA* a;

newdeletenew []およびdelete []は常にペアで使用する必要があります。

より良い解決策は、スマート ポインターを使用することです。

struct tStruct
{
     uint32_t id;
     std::unique_ptr<A> a;
     C b;
};

std::vector<std::unique_ptr<tStruct>> m_vector;

ベクトルからアイテムを削除するには、erase remove イディオムを使用します。

m_vector.erase(std::remove_if(m_vector.begin(), m_vector.end(), 
               [](std::unique_ptr<tStruct>& up){ return up->id == ID; }), 
               m_vector.end());
于 2013-01-30T09:50:48.573 に答える
0

コードにはまだいくつかのメモリリークが含まれています。オブジェクトのプッシュが失敗した場合のプッシュコードには、ロールバックはありません。

tStruct* myStruct = new tStruct;
myStruct->id = ID;
myStruct->a= new A(); //could throw, if it does, then `myStruct` will leak
myStruct->b = c; // c is an object
//could throw, if it does, then `myStruct` and `myStruct->a` will leak
m_vector.push_back(myStruct);

一般に、への手動呼び出しdeleteは、コードがリークしているか、過度に複雑であることを示します。コードがリークしないようにするには、スマートポインターを使用する必要があります。

 struct tStruct{
    uint32_t id;
    std::unique_ptr<A> a;
    C b;
};
std::vector<std::unique_ptr<tStruct>> m_vector;

構築するには:

std::unique_ptr<tStruct> myStruct(new tStruct);
myStruct->id = ID;
myStruct->a.reset(new A());
myStruct->b = c; // c is an object
m_vector.push_back(std::move(myStruct));

特別な削除コードは必要ありません。

于 2013-01-30T09:51:58.637 に答える
0

を使用してヒープにオブジェクトを作成するたびnewに、対応する場所が必要deleteです。そうしないと、リソース (この場合はメモリ) がリークします。

しかし、一般的に言えば(これはあなたの例にも当てはまります)、補助クラスを使用してこれらのリソースを管理するのが最善です。あなたの場合、スマートポインター。C++ 11 では、標準ライブラリはstd::shared_ptr<>、あなたのケースに適したスマート ポインターのように見えます:

struct tStruct{
    uint32_t id;
    std::shared_ptr<A> a;
    C b;
};
std::vector<std::shared_ptr<tStruct>> m_vector;

スマート ポインターを作成することは、生のポインターを作成することと大差ありません。

std::shared_ptr<tStruct> myStruct (new tStruct);
myStruct->id = ID; // Some unique value
myStruct->a.reset(new A());
myStruct->b = c; // c is an object
m_vector.push_back(myStruct);

しかし、今では呼び出しを忘れることができdeleteますstd::shared_ptr<>:

// Some stuff here 
for (uint32_t i = 0; i < m_vector.size(); i++) {
    if (m_vector.at(i)->id == ID) { // Some filtering
        // delete m_vector.at(i); This is no longer needed
        m_vector.erase(m_vector.begin() + i);
    }
}
于 2013-01-30T09:49:24.583 に答える