5

クラスへのポインターのベクトルがあります。デストラクタを呼び出してメモリを解放する必要があります。それらはポインターのベクトルであるため、 vector.clear() は仕事をしません.だから私は手動でそれをやり続けました:

void Population::clearPool(std::vector<Chromosome*> a,int size)
{
    Chromosome* c;
    for(int j = 0 ;j < size-1;j++)
    {
       c = a.back();
       a.pop_back();
       delete c;
       printf("  %d \n\r",j);
       c = NULL;

    }

}

そこにあるprintfは、どの染色体でセグメンテーション違反が発生したかを確認するための話しているデストラクタがあるためです。clearPool() が呼び出され、サイズが 100 になったと言うと、0 から 100 までの任意の染色体でセグメンテーション違反が発生する可能性があります。

なぜこれが起こっているのか分かりませんし、実際に何が悪いのかを見つける方法もありません。なぜなら、ブレークポイントを使ってデバッグしている間、ランダムな染色体で起こっているだけだからです。

コードブロック IDE と gdb デバッガーを使用しています。セグメンテーション違反が発生したときのスタック トレースには、4 つのメモリ アドレスと関数がありますwsncpy()

4

10 に答える 10

5

(@1800INFORMATION)に比べて微修正版。

  struct DeleteFromVector
    {
        template <class T>
        void operator() ( T* ptr) const
        {
            delete ptr;
        }
    };


std::for_each(aVec.begin(), aVec.end(), DeleteFromVector());
于 2009-05-21T08:52:20.223 に答える
3

ちなみに、Boostラムダには、ポインターのシーケンスを削除するためのファンクターが既にあります。

std::for_each(a.begin(), a.end(), boost::lambda::delete_ptr());
于 2009-05-21T09:31:07.150 に答える
1

最も可能性の高い理由は、同じアドレスに対してdeleteを 2 回呼び出していることです。これは、ベクトルに 1 つのオブジェクトを複数回追加した場合に発生する可能性があります。これを検出するには、オブジェクトのアドレスを出力するステートメントを挿入してから、削除します。

printf( "will delete %d\n", (int)c );
delete c;
于 2009-05-21T09:35:11.430 に答える
0

生のポインターの代わりにスマートポインター (ie:auto_ptr) を使用し、各要素のデストラクタを呼び出す vector::clear メソッドを使用することをお勧めします

于 2009-05-21T08:59:28.990 に答える
0

コード内の一部のポインターが正しい Chromosome オブジェクトを参照していないようです。これは、コードの結果としていくつかのオブジェクトを 2 回削除しようとした場合に発生する可能性があります。

Population p;
vector<Chromosome*> chromosomes;
p.clearPool(chromosomes,chromosomes.size()); // You pass by value, so chromosomes is not changed
p.clearPool(chromosomes,chromosomes.size()); // Delete already deleted objects second time

同様のエラーを回避するために、Boost Pointer Container Libraryから便利な ptr_vector を見つけることができます。

于 2009-05-21T09:03:25.393 に答える