删除 3D 矩阵 c++

Delete 3D matrix c++

我正在尝试删除使用 "new" 创建的矩阵,但编译器 return 出现错误消息: "CRT detected that the application wrote to memory after end of heap buffer."

这是我的代码:

//alloc
rede->y = new float**[rede->p];
for (i=0; i < rede->p; i++) {
    rede->y[i] = new float*[rede->c];
    for (j=0; j < rede->c; j++) {
        rede->y[i][j] = new float [rede->n[i] + 1];
    }
}

//...

//d-lloc
for (i=0; i < rede->p; i++) {
    for (j=0; j < rede->c; j++) {
        delete (rede->y[i][j]); //here is the error. If I comment this line, the compiler do not accuse any error.
    }
    delete (rede->y[i]);
}
delete (rede->y);

当我这样尝试时没有出错:

rede->y = new float**[rede->p];
for (i=0; i < rede->p; i++) {
    rede->y[i] = new float*[rede->c];
    for (j=0; j < rede->c; j++) {
        rede->y[i][j] = new float [rede->n[i] + 1];
        delete (rede->y[i][j]);
    }
    delete (rede->y[i]);
}
delete (rede->y);

第一个代码有什么问题? 谢谢

尽管我不提倡使用 float***(三星级编程),但我会尝试向您提供有关您 post 编写的代码的信息。请注意,使用容器 class 可能会更好,例如 std::vector<std::vector<float>>.

我看到的一个错误是您没有使用 delete 的正确形式。由于您分配了一个数组,因此您应该使用 delete[]。即使您只是分配指针或 float,使用错误形式的 delete 也是未定义的行为。

其次,我们不知道 rede->prede->crede->n 的值是什么,因此我们不知道问题是否出在这些变量中。

第三,您的 post 正在使用分配的内存执行某些操作,但您没有向我们展示。可能是您未显示的代码导致内存损坏 - 您应该检查一下。

所以给你看一个例子,这是一个正确编译和释放的程序。

int main()
{
    const int nPages = 5;
    const int nRows = 10;
    const int nCols = 20;
    float ***mat = new float**[nPages];
    for (int i = 0; i < nPages; i++)
    {
        mat[i] = new float*[nRows];
        for (int j = 0; j < nRows; j++)
            mat[i][j] = new float[nCols];
    }

    for (int i = 0; i < nPages; i++)
    {
        for (int j = 0; j < nRows; j++)
            delete [] mat[i][j]; 
        delete [] mat[i];
    }
    delete[] mat;
}

注意 delete[] 的正确用法。

鉴于此,如果矩阵的维度是固定的,那么以下版本减少了对new[]的调用次数,从而使delete[]更容易处理:

int main()
{
    const int nPages = 5;
    const int nRows = 10;
    const int nCols = 20;
    float ***mat = new float**[nPages];
    for (int i = 0; i < nPages; i++)
    {
        mat[i] = new float*[nRows];
        float *pool = new float[nRows * nCols];
        for (int j = 0; j < nRows; j++, pool+=nCols)
            mat[i][j] = pool;
    }

    for (int i = 0; i < nPages; i++)
    {
        delete [] mat[i][0];
        delete [] mat[i];
    }
    delete[] mat;
}

在第一个示例中,对 new[] 的调用总计 56 次。第二个例子只有 11 次调用 new[]。这两个示例完成相同的事情,但使用略有不同的内存分配方式。第二个版本在一次调用 new[] 中分配所有数据,而不是为每一行数据调用 new[]

另请注意,如果列数(最内层维度)增加,第一个示例对 new[] 的调用次数将急剧增加,因为最内层循环必须调用 new[],而在第二种情况下对 new[] 的调用次数保持在 11,无论最内层循环是否增加。

第二个例子中对delete[]的调用也不同,我们只需要deletemat[i][0]就可以删除整页数据,而不用循环删除每一行数据。