关于VTK智能指针使用 vtkSmartPointer的坑

关于vtkSmartPointer的坑,别再无脑使用智能指针了

问题描述

使用VTK写项目时,有时候总报错在Render()行。
说发生访问冲突,然后给一段冲突的地址。
有时是这个,有时是0XFFFFFFFFFFFFFF这种系统内存。
Alt

重启VS或重启电脑之后,问题依旧存在,困扰了很久。可能有几个月。。。

主要是他是偶发的BUG,不一定会遇到,可能隔一周给你来一次,然后放着不管写别的代码去了,然后过一会运行又没了,让人摸不着头脑,很玄学。

踩坑之路

其实也能猜到。这种错误肯定是内存,指针之类的问题。

我一开始放着没管,因为他大概过半小时之后再运行,就不报错了。。。
而且之后都不会再报错。

后面实在受不了了,,我开始找写的有指针的代码。
只有一个读数据的指针,以为是自己没有free()掉自己读的数据。
于是把写在main()最后面的free写在读到vtk数据之后,类似这种

int main(){

FILE* fp = fopen("./Data/test.bin","rb");
UINT8* pInputData = (UINT8*)malloc(volsize);
fread(pInputData,sizeof(UINT8),volsize,fp);
fclose();

...

vtkNew<vtkImageData> pImagedata;
//从imageimport读取到vtkImageData数据
pImagedata.deepcopy(imageimport->getoutput());
free(pInputData);
...
renwin->Render();
//本来写在main结束的free 写在deepcopy之后了
}

之后运行,还真不报错了。
但是后面注释掉那行free(),重新运行多次,仍然不报错。

这就很奇怪了,感觉我free加第一次有用,后面怎么弄都没用了。

然后又过了几天,我直接用vtk的类读一个demo,没用自己的指针读。类似这种

int main(){
vtkSmartPointer<vtkMetaImageReader> reader = vtkSmartPointer<vtkMetaImageReader>::New();
reader->setFileName("./brain.mhd");
reader->update();
...
renwin->Render();
//运行Render也报错。。
}

然后运行也报错,感觉和我的free根本没关系啊。

解决

今天一跑代码又tm遇到了,受不了到要写博客的地步了。

在彻底检查代码,阅读VTK源码,vtk交流群里问大佬之后,我感觉是智能指针的原因。

因为我中间有段代码是类似这样的

void SetProperty(vtkSmartPointer<vtkVolumeProperty> property){
	...
	//设置一些透明度,颜色之类的
}

int main(){
...
vtkSmartPointer<vtkVolumeProperty> prop = vtkSmartPointer<vtkVolumeProperty>::New();
SetProperty(prop);
...
renwin->render();
}

在main里面我创建render,renwin这些进行渲染,但我用写了一个函数调用,在里面设置了体数据渲染的Property。

把此函数参数改成普通指针。运行就正常了。

void SetProperty(vtkVolumeProperty* property){
	...
}

因为我在main函数内用智能指针创建一个对象,在main范围内,以及转为普通普通指针往函数传递的时候都没问题。
但是如果传递函数参数是智能指针,会执行拷贝构造函数,将智能指针相互赋值,然后函数参数的智能指针在函数返回堆栈时,将我在main里面传值的智能指针对象释放了。

这样就在Render的时候,发现渲染过程中需要访问已经被销毁的对象。出现访问冲突。

所以感觉这就是问题的根源!欢迎大佬指正我的理解。

总结

主要是网上搜到的资源都是说什么智能指针能自动管理生命周期,能用智能指针的地方全用智能指针,就不会有内存泄漏。

但我这是还没用完,就给释放的问题。

这篇讲C++智能指针的文章写的很好: https://blog.csdn.net/cpp_learner/article/details/118912592

里面提到了,不要把智能指针相互赋值的问题。特别是禁止用任何类型智能指针get 函数返回的指针去初始化另外一个智能指针!

现在想想,这样函数传参确实使用了多个智能指针,并且相互赋值了。

苟GPT让我这样写的。。。

在这里插入图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值