一. 错误
报错处所在代码:
vtkImageData *newImage = vtkImageData::New();
newImage->Initialize();
newImage->SetSpacing(1, 1, 1);
newImage->SetDimensions(256, 256, 1);
newImage->AllocateScalars(VTK_DOUBLE, 1);
//newImage->Update();
//memcpy(newImage->GetScalarPointer(), *B, sizeof(unsigned char) * x * y * z);
for (k = 0; k < 1; k++)
{
for (i = 0; i < 256; i++)
{
for (j = 0; j < 256; j++)
{
complex<double> * pixe = (complex<double> *)newImage->GetScalarPointer(i, j, k);
*pixe = module[i][j][k];
}
}
}
char tmpFilename[200];
sprintf(tmpFilename, "../mrisimulation/data/Label/%s_%d.mhd\n", "Complex");
//printf("EED SaveVtkImage fileout = %s size = %d %d %d", tmpFilename, dimX, dimY, dimZ);
vtkMetaImageWriter *writer = vtkMetaImageWriter::New();
writer->SetInputData(newImage);
writer->SetFileName(tmpFilename);
writer->Write();
newImage->Delete();
writer->Delete();
printf(" SaveVtkImage end\n");
倒数第二行代码报错,即代码:
writer->Delete();
一运行这个程序,就报这个错误:
Heap block at 000001D7D892BFC0 modified at 000001D7D89ABFD0 past requested size of 80000
输出窗口提示如下:
输出窗口报这个错的同时,弹出对话框,对话框显示:“已触发了一个断点”,然后程序卡主。
二. 原因
通常报这个错有两种原因:
1. 创建的指针指向内存中的一片存储空间,最后该指针用Delete()函数清空这片存储空间的时候,若该指针指向的地址已经发生改变,则报错。
2. 两个指针(指针newImage,指针writer)都指向内存中的一片存储空间,指针newImage已经用Delete()函数清空了这片存储空间,若后来指针writer又用Delete()函数清空一次这片存储空间,则报错。
三. 解决
1.
针对第一个原因,我在创建时和Delete()前分别打印两个指针指向的存储空间的地址:
此处的copywriter和上述代码中的writer是一样的,在此可以看做是同一个指针。通过打印可以看出,两个指针在最初和执行Delete()之前指向的是同一个存储空间。所以第一个原因不成立。
2.
因为
writer->SetInputData(newImage);
这句话,则writer和newImage指向的是同一个存储空间,当执行完:
newImage->Delete();
这句话后,这两个指针指向的存储空间已经被清空。当执行这句话:
writer->Delete();
后,该存储空间又被清空了一次,所以出错。
现在改动代码如下:
指针newImage所指向的存储空间清空后,将指针newImage存储的地址值赋空,然后将指针writer存储的地址值赋空,至于writer将存储空间清空的语句删除。如下:
newImage->Delete();
newImage = NULL;
writer = NULL;
至此,问题解决。