1

私は練習問題をやっていますが、メモリリークがないことを確認するためにデストラクタを作成するよう求められています。このデストラクタを使用すると、system("pause"); の実行後に次のエラーが発生します。

http://imgur.com/r2bvF

コピーコンストラクターは次のとおりです。

    vector_of_int::vector_of_int ( const vector_of_int& a_vector )
    {
        an_array = new int[ a_vector.size ];

        this->size = a_vector.size;
        for( int i = 0; i < size; ++i )
        {
            an_array[i] = a_vector.an_array[i];
        }
    }

および代入演算子:

    vector_of_int& vector_of_int::operator= ( const vector_of_int& a_vector )
    {
        if( this == &a_vector )
        {
            return *this;
        }

        this->size = a_vector.size;
        for( int i = 0; i < size; ++i )
        {
            an_array[i] = NULL;
            an_array[i] = a_vector.an_array[i];
        }
            return *this;
     }

オンラインで少し検索したところ、コピー コンストラクターが同じメモリ位置を指していることが原因である可能性があることがわかりました。これをテストするために、私の main() 関数で、データを各ベクトル a、b、c にプッシュし、それらを再印刷しましたが、それらはすべて異なっていました。このエラーは、デストラクタが呼び出された後に表示され、次の行に進みます system("pause"); 任意のキーを押すと表示されます。main() の末尾は次のとおりです。

    a_vector.~vector_of_int();
    b_vector.~vector_of_int();
    c_vector.~vector_of_int();
    cout << "\n";
    system("pause");
    return 0;

main.exe は、main の中かっこの後にデストラクタを再度呼び出していますか? 3 つのデストラクタ ステートメントすべてにコメントを付けると、エラーは表示されなくなります。

ありがとう。

4

4 に答える 4

9

デストラクタを明示的に呼び出さないでください。これは、オブジェクトがスコープ外になると自動的に発生します (コードから、デストラクタを呼び出すために使用される表記法を考えると、ベクトルはスタックに割り当てられていると思います.)。を使用してヒープに割り当てられた場合newでも、デストラクタを明示的に呼び出すのではなく、 を使用しますdelete

また、代入演算子ではthis->sizeは更新されますが、 は更新されan_arrayません。その場合、十分な要素がないためa_vector.size > this->size、範囲外のアクセスが発生します:および.an_arraydelete[]new[] an_array

于 2012-07-03T19:56:23.840 に答える
2

コードから、デストラクタを明示的に呼び出しているように見えます。それは合法であり、いくつかの用途がありますが、多くの場合、デストラクタを明示的に呼び出すべきではありません。これは、オブジェクトがスコープ外になる (またはdeleteポインタに対して呼び出される) ときに自動的に呼び出されるためです。既に破棄されたオブジェクトに対してデストラクタを実行することは、未定義の動作です。

特定のコードでは、デストラクタはおそらくメモリを解放しています.2回目(ローカル変数のスコープの最後での自動呼び出し)は、手動呼び出しによってすでに解放され、ランタイムエラーをトリガーするメモリを解放しようとします。

于 2012-07-03T19:58:31.030 に答える
1

代入演算子では、アイテムをある配列から別の配列にコピーします。しかし、ローカル配列のサイズがオペレーターに渡されるパラメーターよりも小さい場合はどうなるでしょうか? 配列のサイズを超えます。

于 2012-07-03T20:01:11.683 に答える
1

次のようなベクトルを作成したと思います。

vector_of_int v;

その場合は削除しないでください。自動ストレージです。スコープの最後に自動的に削除されます

ベクトルを次のように作成した場合:

vector_of_int *v = new vector_of_int();

オペレーターを呼び出しdeleteて削除します。

delete v;
于 2012-07-03T19:57:00.773 に答える