PCL使用VoxelGrid出现Segmentation fault (core dumped)的解决办法

今天调个程序,需要对一个点云进行下采样处理,本来很简单的事情,但是总在函数退出的时候出现Segmentation fault,之前是将其独立编译为一个二进制文件,下采样后的点云保存后再退出。这样就算出错也没事,反正数据出来了我哪管bug洪水滔天 😎。

但是在数据量比较大的需求中,这个下采样功能就不能再独立为二进制文件了,因此我不得不修复这个问题。花费了好久终于把这个问题修复了。这个问题就是PCL的问题,只能是利用另一种方式绕过这个bug,得到的结果是一样的,这个放心。现在我把问题及解决方案整理如下

问题引出

简单来说,我需要对一个点云进行下采样,cloudin是原始点云,cloudout是下采样后的点云,关键函数摘出来如下所示:

void downscale(pcl::PointCloud<pcl::PointXYZ>::Ptr cloudin, float leafsize,
			   pcl::PointCloud<pcl::PointXYZ>::Ptr cloudout)
{
  LOG(INFO) << "cloudin size: " << cloudin->points.size();
  pcl::VoxelGrid<pcl::PointXYZ> downSizeFilterCorner;
  downSizeFilterCorner.setLeafSize(leafsize, leafsize, leafsize);
  downSizeFilterCorner.setInputCloud(cloudin);
  downSizeFilterCorner.filter(*cloudout);
  LOG(INFO) << "cloudout size: " << cloudout->points.size();
}

执行后,代码输入如下所示,整体功能都能运行,但是在结束,进行内存释放时候,出现了Segmentation fault (core dumped)

I0628 test_pclVoxelGrid.cpp] cloudin size: 473300
I0628 test_pclVoxelGrid.cpp] cloudout size: 19180
Segmentation fault (core dumped)

问题分析

利用valgrind工具进行内存检查valgrind --tool=memcheck --leak-check=full --show-reachable=yes ./build/test_pclVoxelGrid,代码中存在内存溢出问题。

==21349== 306,880 bytes in 1 blocks are definitely lost in loss record 249 of 249
==21349==    at 0x4C330B5: malloc (vg_replace_malloc.c:431)
==21349==    by 0x5AF1A88: Eigen::internal::aligned_malloc(unsigned long) (in /usr/lib/x86_64-linux-gnu/libpcl_filters.so.1.8.1)
==21349==    by 0x5B057D0: std::vector<pcl::PointXYZ, Eigen::aligned_allocator<pcl::PointXYZ> >::_M_default_append(unsigned long) (in /usr/lib/x86_64-linux-gnu/libpcl_filters.so.1.8.1)
==21349==    by 0x5CE4D28: pcl::VoxelGrid<pcl::PointXYZ>::applyFilter(pcl::PointCloud<pcl::PointXYZ>&) (in /usr/lib/x86_64-linux-gnu/libpcl_filters.so.1.8.1)
==21349==    by 0x1218CC: pcl::Filter<pcl::PointXYZ>::filter(pcl::PointCloud<pcl::PointXYZ>&) (in test_pclVoxelGrid)
==21349==    by 0x118127: main (in test_pclVoxelGrid)
==21349==
==21349== LEAK SUMMARY:
==21349==    definitely lost: 306,880 bytes in 1 blocks
==21349==    indirectly lost: 0 bytes in 0 blocks
==21349==      possibly lost: 0 bytes in 0 blocks
==21349==    still reachable: 81,172 bytes in 1,006 blocks
==21349==         suppressed: 0 bytes in 0 blocks
==21349==
==21349== For lists of detected and suppressed errors, rerun with: -s
==21349== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 0 from 0)

在gg上搜了一大圈,大部分给出的建议是取消"c++11",或者用"c++11"重新编译下自己使用的PCL库,但这些都不现实,终于在《Segmentation fault when deallocating pcl::PointCloud》找到了解决办法。

pcl::PointCloud<pcl::PointXYZ>转为pcl::PCLPointCloud2后下采样,然后再还原为原始格式点云,就可以规避这个问题了。

解决方案

前面的downscale更换为如下代码

void downscale(pcl::PointCloud<pcl::PointXYZ>::Ptr cloudin, float leafsize,
			   pcl::PointCloud<pcl::PointXYZ>::Ptr cloudout)
{
  pcl::PCLPointCloud2::Ptr tmpcloud(new pcl::PCLPointCloud2());
  pcl::PCLPointCloud2::Ptr cloud_filtered(new pcl::PCLPointCloud2());
  
  LOG(INFO) << "cloudin size: " << cloud->points.size();
  pcl::toPCLPointCloud2(*cloudin, *tmpcloud);
  
  pcl::VoxelGrid<pcl::PCLPointCloud2> sor;
  sor.setInputCloud(tmpcloud);
  sor.setLeafSize(leafsize, leafsize, leafsize);
  sor.filter(*cloud_filtered);

  pcl::fromPCLPointCloud2(*cloud_filtered, *cloudout);
  LOG(INFO) << "cloudout size: " << cloudout->points.size();
}

执行后,代码输入如下所示,输出的结果是一样的,而且也没有前面的错误了,问题Solved 💪 。

I0628 test_pclVoxelGrid.cpp] cloudin size: 473300
I0628 test_pclVoxelGrid.cpp] cloudout size: 19180

终于干掉了这个Bug,请叫我铲B官😎 。

  • 5
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值