空指针引发的灾难——一下午debug

在将PCL颜色区域增长功能整合到界面时遇到程序闪退问题,错误提示涉及空指针。排查过程中,首先考虑了boost智能指针未初始化的情况,但发现所有指针已正确初始化。最终发现是spinBox焦点触发的segmentation()函数在空指针上执行操作导致。修复方法是确保在操作前检查指针是否为空,以避免空指针异常。此经验强调了确保类数据成员稳定性和谨慎处理指针的重要性。

1问题描述

在将PCL的颜色区域增长分割这个小功能做入界面时,出现了闪退现象,无论点击界面的哪一个位置,都立即退出程序,并伴有如下报错内容:

main: /usr/include/boost/smart_ptr/shared_ptr.hpp:641:typename boost::detail::sp_dereference<T>::type boost::shared_ptr<T>::operator*() const [with T = pcl::PointCloud<pcl::PointXYZRGB>; typename boost::detail::sp_dereference<T>::type = pcl::PointCloud<pcl::PointXYZRGB>&]: 假设 ‘px != 0’ 失败。
Aborted
Makefile:10: recipe for target 'run' failed
make: *** [run] Error 134

2问题解决

网上查询后,一开始以为是定义了boost smart pointer但是没有给它分配内存空间,如下这种情况:

pcl::PointCloud<pcl::PointXYZ>::Ptr cloud; 
    for (int i = 0; i < 10; i++) 
    { 
        for (int j = 0; j < 10; j++) 
        { 
            pcl::PointXYZ point; 
            point.x = i; 
            point.y = j; 
            point.z = 0; 
            cloud->push_back(point); 
        } 
    }

应该写为:

pcl::PointCloud<pcl::PointXYZ>::Ptr cloud (new pcl::PointCloud<pcl::PointXYZ>);

但是仔细检查了程序,所有ptr指针都有初始化。

后来无意间发现界面打开的时候,spinBox处于focus状态,而我定义了:

connect(ui->spinBox, SIGNAL(editingFinished()), this, SLOT(segmentation()));

因此点击界面任何一个地方都会发出信号editingFinished(),然后执行槽函数segmentation(),问题就出在了这个函数:

pcl::RegionGrowingRGB<PointT> reg;
reg.setInputCloud (cloudin);      //此时cloudin无数据!!!
reg.setIndices (indices);
reg.setSearchMethod (tree);
reg.setDistanceThreshold (DistanceThreshold);
reg.setPointColorThreshold (PointColorThreshold);
reg.setRegionColorThreshold (RegionColorThreshold);
reg.setMinClusterSize (MinClusterSize);

std::vector <pcl::PointIndices> clusters;
reg.extract (clusters);

cloudout = reg.getColoredCloud ();//返回一个空指针!!!

因为输入点云为空, 输出结果是一个空指针,而后面只要操作这个空指针(赋值,被赋值,写入,读出,查看点云属性等等),可能就会出现上述报错内容。

之后程序改为:

PointCloudT::Ptr colored_cloud = reg.getColoredCloud ();//定义临时指针存储返回值

if(clusters.size()==0)//如果分割失败直接返回
  {
      cout<<"Failure in rgb clustering.\nPlease try some other parameters."<<endl;
      return;
  }
 else
  {
      cout<<"Success in rgb clustering."<<endl;
      *cloudout = *colored_cloud;//分割成功再给cloudout赋值,保证了cloutout用在程序的任何地方都是初始化好的指针
      viewer->removePointCloud("v2");       
      PointCloudColorHandlerRGBField<PointT> rgb2(cloudout);  
      viewer->addPointCloud<PointT>(cloudout, rgb2, "v2", v2); 
      ui->qvtkWidget->update();

  }

3启发

对于类的书写,要保证好数据成员的稳定性,因为任何函数成员都可以使用它。尤其是处理指针时一定要谨慎,不要让数据成员有空指针的可能性。

4参考

pcl问答社区shared_ptr问题

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值