2013-03-25 57 views
1

我一直在盯着這一段時間,我不明白爲什麼它會失敗。我有一個CMATRIX類,並實現二維矩陣,就像這樣:釋放2D陣列時不匹配的刪除

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(); 
} 

它正常工作,直到我試圖摧毀它。有兩種方法負責分配和解除分配,定義如下:

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=0中獲得打印。它不會爲其他i s,也不會刪除[]。

我在做什麼錯?

回答

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[]編輯。

+0

該死。你是對的。謝謝 – 2013-03-25 11:16:40

1

除此之外鑑定delete[]delete問題以前的答案,注意,你也應該定義一個拷貝構造函數operator=CMatrix類(或者宣佈private禁止複製語義),因爲你直接管理班級中的原始資源(即動態分配的內存)。 有關更多詳細信息,請參見Rule of Three

或者您可以簡單地使用直接資源管理器std::vector,而不是使用new[]分配內存。您還可以定義嵌套向量來構建2D矩陣,如vector<vector<double>>。通過這種方式,std::vector將自動正確執行內存分配,清理和複製。

+0

我實際上有這些在我的代碼(以及+, - ,*等),他們只是沒有關聯,所以我省略了他們,以儘量減少問題的長度。不過,你是對的。在這種特殊情況下,矢量被禁止,因爲這是我正在做的學業工作的一部分 – 2013-03-25 20:42:00

1

你刪除功能不會刪除您在每行的colums分配的內存塊

代碼應該是這樣的

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