高翔slam project0.3出现double free or corruption (out)问题解决

本文详细描述了在高翔SLAM项目中遇到的双释放或腐败(out)错误,并分享了解决方案。通过调整CMake配置,移除-march=native编译选项,成功解决了运行时的崩溃问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

问题

高翔slam project 0.3 在make的时候一切正常。但是在运行的时候会报错:double free or corruption (out)
在用gdb调试的时候,可以知道调试信息:

double free or corruption (out)

Program received signal SIGABRT, Aborted.
__GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:51
51	../sysdeps/unix/sysv/linux/raise.c: 没有那个文件或目录.
(gdb) bt
#0  0x00007ffff57d9e97 in __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:51
#1  0x00007ffff57db801 in __GI_abort () at abort.c:79
#2  0x00007ffff5824897 in __libc_message (action=action@entry=do_abort, fmt=fmt@entry=0x7ffff5951b9a "%s\n")
    at ../sysdeps/posix/libc_fatal.c:181
#3  0x00007ffff582b90a in malloc_printerr (str=str@entry=0x7ffff5953870 "double free or corruption (out)") at malloc.c:5350
#4  0x00007ffff5832e75 in _int_free (have_lock=0, p=0x555555821f10, av=0x7ffff5b86c40 <main_arena>) at malloc.c:4278
#5  0x00007ffff5832e75 in __GI___libc_free (mem=0x555555821f20) at malloc.c:3124
#6  0x00007ffff50ecc4d in g2o::EdgeProjectP2MC_Intrinsics::~EdgeProjectP2MC_Intrinsics() () at /usr/local/lib/libg2o_types_sba.so
#7  0x00007ffff557b1f7 in g2o::Factory::registerType(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, g2o::AbstractHyperGraphElementCreator*) () at /usr/local/lib/libg2o_core.so
#8  0x00007ffff50e4b1a in _GLOBAL__sub_I_types_sba.cpp () at /usr/local/lib/libg2o_types_sba.so
#9  0x00007ffff7de5733 in call_init (env=0x7fffffffdc60, argv=0x7fffffffdc48, argc=2, l=<optimized out>) at dl-init.c:72
#10 0x00007ffff7de5733 in _dl_init (main_map=0x7ffff7ffe170, argc=2, argv=0x7fffffffdc48, env=0x7fffffffdc60) at dl-init.c:119
#11 0x00007ffff7dd60ca in _dl_start_user () at /lib64/ld-linux-x86-64.so.2
#12 0x0000000000000002 in  ()
#13 0x00007fffffffe01a in  ()
#14 0x00007fffffffe060 in  ()
#15 0x0000000000000000 in  ()

刚开始以为是g2o的问题,所以一直在搜索。

解决

就在高翔slam的gihub网址上看到了解决方案:link
set( CMAKE_CXX_FLAGS "-std=c++11 -march=native -O3" )改成set( CMAKE_CXX_FLAGS "-std=c++11 -O3" )
就删掉了一个-march=native然后重新编译,居然就可以运行了 。

资料查阅

可是据我所知-march=native应该是一个指定目标程序的cpu架构来进行程序优化。native就是相当于自检测cpu。总之-march是gcc优化选项。
具体参考:link

我查阅到gcc官网记录了这个bug:Bug c/70136
不过环境不一样,我的机器是:

Intel i7 6700k
ubuntu 18.04
gcc 5.5

具体原因后期再看,不过应该是环境的原因,和代码没关系。

5.6更新

貌似只要加了-march=native
所有的节点与边的析构函数都会报错。

<think>好的,我现在需要解决用户提到的ORB-SLAM中出现“double free or corruption (out)”错误的问题。用户还提到内存泄漏,想用GDB和Valgrind调试。我得先理清这个问题可能的原因和解决方法。 首先,用户提供的引用[3]中提到,出现这个错误是因为编译时使用了-march=native选项,删除后解决了。所以可能需要检查CMakeLists中的编译选项,尤其是是否有-march=native,并建议用户将其删除。这可能与特定CPU架构优化导致的问题有关,删除后重新编译可能避免错误。 接下来,用户想用调试工具排查内存问题。我应该分步骤说明如何使用GDB和Valgrind。比如,用GDB运行程序,捕获崩溃时的堆栈跟踪;用Valgrind检查内存错误,比如非法读写、内存泄漏等。同时,要提醒用户编译时加上-g选项以保留调试信息。 另外,用户提到的double free可能涉及重复释放同一内存区域,或内存越界。可能的原因包括:1. 代码中存在重复delete或free;2. 指针未正确初始化或释放后再次使用;3. 容器操作越界,如vector的越界访问。需要检查相关代码,尤其是涉及内存管理的部分,比如特征点、地图点的创建和释放。 还可能涉及到第三方库的兼容性问题,比如DBoW2或g2o的编译选项是否有问题。需要确保所有依赖库都使用相同的编译选项,避免冲突。此外,内存泄漏可能由于未正确释放动态分配的对象,可以用Valgrind的--leak-check=full选项来定位泄漏点。 需要给用户一个系统的解决步骤:首先检查编译选项,删除-march=native;然后使用调试工具逐步排查;再检查代码中的内存管理,尤其是容易出错的模块;最后确保依赖库的正确编译。同时,引用提供的解决方案中的步骤,如修改CMakeLists.txt,并重新编译所有相关部分。</think>### ORB-SLAM中"double free or corruption"问题排查指南 #### 一、问题原因分析 "double free or corruption (out)"错误通常由以下原因导致: 1. 内存重复释放:同一指针被多次`delete`或`free`[^3] 2. 内存越界访问:对数组、容器进行越界写操作(如`vector`越界访问) 3. 第三方库编译参数冲突:如使用`-march=native`导致的CPU指令集兼容性问题 #### 二、基础解决方案 1. **修改编译参数**(关键步骤) 在ORB_SLAM2、DBoW2、g2o的`CMakeLists.txt`中: ```cmake # 原语句(删除-march=native) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -O3") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -O3") ``` 重新执行`build.sh`完整编译 2. **检查三维坐标计算代码** 在`Optimizer.cpp`和`Sim3Solver.cpp`中,确保三维坐标计算正确: ```cpp // 修改后的正确写法 x3D = cv::Matx31f( x3D_h.get_minor<3,1>(0,0)(0)/x3D_h(3), x3D_h.get_minor<3,1>(0,0)(1)/x3D_h(3), x3D_h.get_minor<3,1>(0,0)(2)/x3D_h(3)); ``` 避免矩阵运算错误导致的内存破坏[^2] #### 三、高级调试方法 1. **GDB调试** ```bash # 编译时添加调试符号 cmake -DCMAKE_BUILD_TYPE=Debug .. # 启动GDB gdb ./Examples/Monocular/mono_tum # 设置断点和运行 (gdb) break main (gdb) run ``` 2. **Valgrind内存检测** ```bash valgrind --tool=memcheck --leak-check=full \ --show-reachable=yes --track-origins=yes \ ./Examples/Monocular/mono_tum ``` 重点关注以下输出: ```log ==1234== Invalid write of size 4 ==1234== at 0xABCDEF: KeyFrame::UpdateConnections() (KeyFrame.cc:123) ==1234== Address 0x123456 is 0 bytes after a block of size 512 alloc&#39;d ``` 3. **核心转储分析** ```bash ulimit -c unlimited # 启用核心转储 ./program # 触发崩溃后生成core文件 gdb ./program core # 分析崩溃现场 ``` #### 四、重点关注模块 1. **地图点管理**(MapPoint.cc) - `UpdateNormalAndDepth()`中的矩阵运算 - `Replace()`方法的指针替换逻辑 2. **关键帧系统**(KeyFrame.cc) - `AddConnection()`中的共享指针管理 - `EraseConnection()`的迭代器有效性 3. **优化模块**(Optimizer.cpp) - 图优化中的顶点/边内存管理 - g2o::SparseOptimizer的clear()调用时序 #### 五、预防措施 1. 使用智能指针: ```cpp std::shared_ptr<MapPoint> pMP = std::make_shared<MapPoint>(); ``` 2. 容器操作防护: ```cpp // 添加元素前检查容量 if (mvpMapPoints.size() <= idx) mvpMapPoints.resize(idx+1); ``` 3. 内存屏障保护: ```cpp std::atomic_thread_fence(std::memory_order_release); ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值