PCL1.8.0执行GreedyProjection三角化时在Memory.h内存释放处崩溃如何解决?
问题产生原因
- Eigen内存对齐不匹配:PCL 1.8.0依赖的Eigen库对包含内置向量的结构(比如
PointNormal、PolygonMesh内部存储的点数据)默认要求16字节对齐,编译时如果项目编译选项和PCL库编译时的对齐规则不一致,会导致内存分配/释放时指针对齐状态不匹配,最终在调用aligned_free释放非对齐指针时崩溃。 - 输入数据异常:如果输入点云点数少于你设置的K搜索值20,会导致法向计算失败输出NaN值,后续三角化处理非法数据时触发内存越界,释放损坏的内存块时报错。
- 参数设置不匹配:你设置的搜索半径
25如果和当前点云的实际分辨率差距过大,会导致三角化过程中异常分配大量内存,触发内存结构损坏。
修复方案
1. 修正编译配置解决对齐问题
在项目的CMakeLists.txt中添加如下编译配置,统一对齐规则:
# 开启原生指令优化,保证内存对齐规则和PCL编译时一致 add_compile_options(-march=native) # 关闭Eigen静态对齐,避免不同编译单元对齐规则冲突 add_definitions(-DEIGEN_DONT_ALIGN_STATICALLY)
如果修改编译配置后仍然崩溃,可以将函数返回值从值传递改为指针传递,避免栈拷贝时的对齐错误:
// 修改函数签名 pcl::PolygonMesh::Ptr triangulationGreedyProjection(pcl::PointCloud<pcl::PointXYZ>::Ptr xyzCloud) { // ...原有逻辑不变... pcl::PolygonMesh::Ptr mesh(new pcl::PolygonMesh); gp3.reconstruct(*mesh); return mesh; }
2. 增加输入和中间结果校验
在法向计算完成后添加合法性校验,提前拦截非法数据:
// 输入点云点数校验 if (xyzCloud->size() < 20) { return pcl::PolygonMesh(); // 或者返回空指针,根据修改后的函数签名调整 } // ...法向计算逻辑... // 法向合法性校验 for (const auto& normal : normals->points) { if (!pcl::isFinite(normal)) { return pcl::PolygonMesh(); } }
3. 适配点云调整三角化参数
先统计输入点云的平均点间距,将setSearchRadius的参数设置为平均点间距的2~3倍,避免搜索范围不合理导致的内存异常。
4. 版本升级备选
PCL 1.8.0存在多个已知的Eigen对齐相关bug,如果以上方案都无法解决,可将PCL版本升级到1.9及以上,对应问题已经被官方修复。
内容的提问来源于stack exchange,提问作者alimagic
相关产品推荐
相关产品推荐

