删除3D矩阵c ++

时间:2015-02-19 16:34:11

标签: c++ matrix dynamic-memory-allocation

我试图删除创建的矩阵" new",但编译器会返回错误消息: " CRT检测到应用程序在堆缓冲区结束后写入内存。"

那是我的代码:

//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);

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

1 个答案:

答案 0 :(得分:0)

即使我不提倡使用float***(三星级编程),我也会尝试为您提供有关您发布的代码的信息。请注意,使用容器类(例如std::vector<std::vector<float>>

)可能会更好

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

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

第三,你的帖子正在用这个分配的内存做一些事情,但你没有告诉我们。可能是您未显示的代码导致内存损坏 - 您应该检查这一点。

为了向您展示一个示例,这里有一个正确编译和解除分配的程序。

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[]的调用也有所不同,因为我们只需要删除mat[i][0]来删除整个数据页,而不必循环删除每一行数据。