C++关于堆栈报错的一个实例及其解决方法

一. 错误

报错处所在代码:

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

输出窗口提示如下:

083806_1VZw_614348.png

输出窗口报这个错的同时,弹出对话框,对话框显示:“已触发了一个断点”,然后程序卡主。

二. 原因

通常报这个错有两种原因:

1. 创建的指针指向内存中的一片存储空间,最后该指针用Delete()函数清空这片存储空间的时候,若该指针指向的地址已经发生改变,则报错。

2. 两个指针(指针newImage,指针writer)都指向内存中的一片存储空间,指针newImage已经用Delete()函数清空了这片存储空间,若后来指针writer又用Delete()函数清空一次这片存储空间,则报错。

三. 解决

1. 

针对第一个原因,我在创建时和Delete()前分别打印两个指针指向的存储空间的地址:

090922_csOU_614348.png

此处的copywriter和上述代码中的writer是一样的,在此可以看做是同一个指针。通过打印可以看出,两个指针在最初和执行Delete()之前指向的是同一个存储空间。所以第一个原因不成立。

2.

因为

writer->SetInputData(newImage);

这句话,则writer和newImage指向的是同一个存储空间,当执行完:

newImage->Delete();

这句话后,这两个指针指向的存储空间已经被清空。当执行这句话: 

writer->Delete();

后,该存储空间又被清空了一次,所以出错。

现在改动代码如下:

指针newImage所指向的存储空间清空后,将指针newImage存储的地址值赋空,然后将指针writer存储的地址值赋空,至于writer将存储空间清空的语句删除。如下:

newImage->Delete();
newImage = NULL;
writer = NULL;

至此,问题解决。 

转载于:https://my.oschina.net/wangsifangyuan/blog/1516577

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值