1

私はこれをしばらく見つめていましたが、なぜ失敗するのかわかりません。次のような2Dマトリックスを実装するCMatrixクラスがあります。

class CMatrix {
public:
    CMatrix(int height, int width);
    ~CMatrix();
    // more stuff here
private:
    void deleteData();
    void allocData(int height, int width);

    int rows, cols;
    double** data;
};

CMatrix::CMatrix(int height, int width) {
    allocData(height, width);
}

CMatrix::~CMatrix() {
    deleteData();
}

私がそれを破壊しようとするまで、それはうまくいきます。次のように定義された、割り当てと割り当て解除を担当する2つの方法があります。

void CMatrix::allocData(int height, int width) {
    this->rows = height;
    this->cols = width;

    data = new double*[rows];
    for (int i = 0; i < rows; i++) {
        data[i] = new double[cols];
        for (int j = 0; j < cols; j++)
            data[i][j] = 0;
    }
}

void CMatrix::deleteData() {
    for (int i = 0; i < rows; i++) {
        delete data[i];
    }
    delete [] data;
}

この単純なmainコードにより、誤動作が発生します。

int main(int argc, char** 

    CMatrix a(2, 3);
    a[0][0] = 1;
    a[0][1] = 2;
    a[0][2] = 3;
    a[1][0] = 4;
    a[1][1] = 5;
    a[1][2] = 6;

    return 0;
}

valgrindはこれを言います:

==21005== Mismatched free() / delete / delete []
==21005==    at 0x4C2A44B: operator delete(void*) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==21005==    by 0x402B5C: CMatrix::deleteData() (main.cpp:375)
==21005==    by 0x401731: CMatrix::~CMatrix() (main.cpp:138)
==21005==    by 0x402F5D: main (main.cpp:598)
==21005==  Address 0x5a06090 is 0 bytes inside a block of size 24 alloc'd
==21005==    at 0x4C2AAA4: operator new[](unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==21005==    by 0x402A84: CMatrix::allocData(int, int) (main.cpp:366)
==21005==    by 0x4015FB: CMatrix::CMatrix(int, int) (main.cpp:123)
==21005==    by 0x402D63: main (main.cpp:415)

このメッセージは、メソッドdeleteData()および。にあるときに出力されますi=0i他のsについても、delete[]についても何も言いません。

私は何が間違っているのですか?

4

3 に答える 3

3

delete[]次のように割り当てられているため、各行で使用する必要がありnew[]ます。

for (int i = 0; i < rows; i++) {
    delete[] data[i];
}

[i]最後のは配列の添え字であり、とは関係がないことに注意してくださいdelete[]。次のように考えてください。

for (int i = 0; i < rows; i++) {
    double* p = data[i];
    delete[] p;
}

動的に割り当てられた配列の最初の要素を指すため、編集pする必要があります。delete[]

于 2013-03-25T11:05:46.313 に答える
1

delete[]識別された前の回答と問題に加えて、コピーコンストラクターとクラスを定義する(またはコピーセマンティクスを禁止するように宣言する)delete必要があることに注意してください。これは、でrawリソース(つまり動的に割り当てられたメモリ)を直接管理しているためです。クラス。詳細については、三つのルールを参照してください。operator=CMatrixprivate

または、メモリを。で割り当てる代わりに、のような直接リソースマネージャを使用することもできます。のように、ネストされたベクトルを定義して2D行列を作成することもできます。このようにして、メモリの割り当て、クリーンアップ、およびコピーが自動的に適切に実行されます。std::vectornew[]vector<vector<double>>std::vector

于 2013-03-25T11:29:49.660 に答える
1

削除機能は、各行の列に割り当てたメモリブロックを削除しません

コードは次のようになります

void CMatrix::deleteData() {
    for (int i = 0; i < rows; i++) {
        delete[] data[i];
    }
    delete [] data;
}
于 2013-03-25T11:43:57.623 に答える