我试图删除创建的矩阵" 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);
第一个代码有什么问题? 感谢。
答案 0 :(得分:0)
即使我不提倡使用float***
(三星级编程),我也会尝试为您提供有关您发布的代码的信息。请注意,使用容器类(例如std::vector<std::vector<float>>
。
我看到的一个错误是你没有使用delete
的正确形式。由于您分配了一个数组,因此您应该使用delete[]
。即使您只是分配指针或float
,使用错误形式的delete
也是未定义的行为。
其次,我们不知道rede->p
,rede->c
或rede->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]
来删除整个数据页,而不必循环删除每一行数据。