在调用 StatisticalOutlierRemoval
时遇到 double free or corruption
我在 PCL
源代码中加入了一些log,具体如下:
1 | 2: [INFO]1712543988.313661216: filter - CropBox |
PCL 的 filter 函数里只包括了 initCompute()
applyFilter()
deinitCompute()
三个部分。
在正常情况,也就是跑 CropBox
的时候,程序会进入 deinitCompute()
。而下面跑 StatisticalOutlierRemoval
的时候,明显它没有进入到 deinitCompute()
,没有打印里面的log,就以 double free or corruption (out)
结束了。
使用 gdb
追踪
1 | --- FilterIndices h - call deinitCompute() |
其中 vision::cloud::filter_sor
是我自定义的函数,里面就是调用了 PCL
的 StatisticalOutlierRemoval
。
从 gdb
的结果来看,是 PCL
内部 free
的时候出了问题。
Fix
Eigen has a custom mechanism to guarantee aligned memory (used for everything older than C++17, see Memory.h in the Eigen project). If PCL is compiled with C++14 and the user project is compiled with C++17, this will lead to problems (e.g. memory allocated with the custom mechanism but freed without it). Defining EIGEN_HAS_CXX17_OVERALIGN=0 forces Eigen in the user project to use Eigen’s custom mechanism, even in C++17 and newer.
也就是说,由于 PCL
使用了 Eigen
的一种特殊对齐方式,当 PCL
使用 C++14
但用户程序使用 C++17
编译时,由于内存对齐方式不一致,将可能导致 double free
。
那么修复方式:
- 使用相同版本的
C++
编译PCL
和用户程序 - 在
PCL
的cmake
文件中判断C++
版本并设置EIGEN_HAS_CXX17_OVERALIGN
- 在用户程序的
camke
中设置EIGEN_HAS_CXX17_OVERALIGN
1
add_definitions(-DEIGEN_HAS_CXX17_OVERALIGN=0)