【问题标题】:Mismatched delete when freeing 2D array释放二维数组时删除不匹配
【发布时间】:2013-03-14 20:22:14
【问题描述】:

我一直在关注这个问题,但我不明白它为什么会失败。我有一个 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();
}

它工作正常,直到我试图摧毁它。有两种方法负责分配和释放,定义如下:

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 中打印此消息。对于其他is 和 delete[],它什么也没说。

我做错了什么?

【问题讨论】:

    标签: c++ memory-leaks destructor


    【解决方案1】:

    您需要在每一行上使用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[]ed。

    【讨论】:

      【解决方案2】:

      除了前面提到的delete[]delete 问题的答案之外,请注意,您还应该为您的CMatrix 类(或声明它们private 以禁止复制语义),因为您在类中直接管理原始资源(即动态分配的内存)。 有关详细信息,请参阅Rule of Three

      或者您可以简单地使用像std::vector 这样的直接资源管理器,而不是使用new[] 分配内存。您还可以定义嵌套向量来构建二维矩阵,例如 vector&lt;vector&lt;double&gt;&gt;。这样std::vector就会自动正确的进行内存分配、清理和复制。

      【讨论】:

      • 我的代码中实际上有这些(以及 +、-、* 等),它们只是不相关,所以我省略了它们以最小化问题长度。不过,你是对的。在这种特殊情况下禁止使用矢量,因为这是我正在做的学校作业的一部分
      【解决方案3】:

      您的删除函数不会删除您为每行中的列分配的内存块

      代码应该是这样的

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2022-01-15
        • 2023-04-10
        • 2016-03-15
        • 1970-01-01
        • 2015-08-23
        • 1970-01-01
        相关资源
        最近更新 更多