1. 找不到共享库1.1. 现象error while loading shared xxx.so1.2. 原因分析默认情况下编译器只会使用/lib和/usr/lib这两个目录下的库文件通常通过源码包进行安装时如果不指定--prefix会将库安装在/usr/local/lib目录下当运行程序需要链接动态库时提示找不到相关的.so库会报错。也就是说/usr/local/lib目录不在系统默认的库搜索目录中需要将目录加进去。1.3. 解决方法如果共享库文件安装到了/lib或/usr/lib目录下那么需执行一下ldconfig命令如果共享库文件安装到了/usr/local/lib(很多开源的共享库都会安装到该目录下)或其它非/lib或/usr/lib目录下,把新共享库目录加入到共享库配置文件/etc/ld.so.conf中。例如添加下面两行/usr/lib64 /opt/ros/kinetic/lib然后再执行ldconfig命令如果共享库文件安装到了其它非/lib或/usr/lib目录下但是又不想在/etc/ld.so.conf中加路径(或者是没有权限加路径).那可以export一个全局变量LD_LIBRARY_PATH然后运行程序的时候就会去这个目录中找共享库LD_LIBRARY_PATH的意思是告诉loader在哪些目录中可以找到共享库。可以设置多个搜索目录这些目录之间用冒号分隔开。比如安装了一个mysql到/usr/local/mysql目录下其中有一大堆库文件在/usr/local/mysql/lib下面则可以在.bashrc或.bash_profile或shell里加入以下语句即可export LD_LIBRARY_PATH/usr/local/mysql/lib:$LD_LIBRARY_PATH一般来讲这只是一种临时的解决方案在没有权限或临时需要的时候使用2. 无法获取内存2.1. 现象error reading variable: Cannot access memory at address2.2. 原因分析一般是因为使用了未分配内存的指针3. double free2.3. 现象double free or corruption (out)2.3. 原因分析cmake编译选项问题可能是编译时加了下面的选择而编译链接库时却没有加set(CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS} -marchnative)-marchnativeis a destructive flag. It makes the binary possible not compatible on a lot of hardware (basically any CPU that is not a direct descendent of the one used for compilation). It is simply too dangerous to enable this by default.Another important thing to consider is that-marchnatives main end use is optimization. The default optimization flag is-O0(no optimization) so it wouldnt make sense from this perspective either to enable it by default.-marchnative 是gccg编译器的编译选项开启后编译器也就是 gcc/g) 会自动检测电脑CPU型号根据内置的数据库查询该CPU型号支持何种增强指令集比如各版本的SSE AVX等等如果某个指令集可用在编译器编译、优化代码时会尝试“擅作主张”将它认为可以优化的操作使用这些指令集替代以期得到更快的执行效率。这么一看是皆大欢喜的事情但问题在于 SSE AVX这类指令集大多要求参与计算的操作数需要按照一定的格式在内存中存储比如常见的4字节对齐或者16字节对齐个别指令还要求某个操作数必须放置在特定的 CPU Cache里。如果只是单独编译一个文件这没有什么问题可在大部分应用场景中我们自己编译的程序需要连接到第三方库。这个时候问题就来了如果第三方库编译时没有启用-marchnative那么其变量都是按照编译器默认规则分配在内存中的如果此时咱们自己的程序启用了-marchnative那么涉及到可用增强指令集加速的变量则大概率是按照前面4字节对齐、16字节对齐等格式保存在内存中的。如果发生了函数的参数传递、函数调用等操作第三方库代码并不了解咱们已经使用了增强指令集加速还是会按照默认方式解析实参堆栈就会出现获取了错误参数的情况同时咱们自己写的程序也会出现尝试使用第三方库返回的非内存对齐的变量使得增强指令集无法正确寻址这些指令一般只能从4或者16等数字的倍数地址处获取数据从而产生内存非法访问。一般来说报错是Sgement fault但也正由于发生错误可能是数据指针不对、也可能是访问地址不对因此实际报错也会出现你遇到的double free的情况。许多的博客说将-marchnative去掉就可以不报错了我不认同。之所以有这个论断是 在Ubuntu下几乎所有使用apt-get这种二进制安装方法安装到第三方库为了兼容性一般提前编译时不打开-marchnative所以咱们自己的程序不打开-marchnative大部分情况下是可以确保编译通过的。但是如果自己手动编译安装了第三方库比如PCL编译时启用了-marchnative那么咱们自己的程序调用它时如果不加--marchnative 反而会报错。4. 同时链接了动态库与静态库4.1. 现象ERROR: something wrong with flag xxx in file xxx. One possibility: file xxx is being linked both statically and dynamically into this executable.4.2. 原因分析按照经验这是因为运行时的链接库路径中同时包含动态库和静态库修改LD_LIBRARY_PATH让它只包含动态库即可。5. 函数调用过程中变量值不同5.1. 现象定义了一个成员变量struct State { double time; Eigen::Quaterniond q; }该变量以const引用的方式传参进行函数调用时在函数调用前值是正常的进入函数内值就不正常了调用完返回后值又正常了。如果把其中的q去掉或者替换成Eigen::Vecotor3d类型就不会出这个问题。5.2. 原因分析因为上述的被调函数和调用它的函数处在不同的链接库中而这两个库在编译时使用了不同的编译选项这会导致Eigen::Quaterniond在内存解析时会有所有不同而调用时使用的又是const引用的方式进行传参所以会出此问题。5.3. 解决方法所有编译产出包括链接库和可执行文件都使用相同的编译选项6. 成员变量崩溃6.1. 现象通过智能指针调用类的成员函数很多功能都可以正常运行唯独崩溃在成员变量处。received signal SIGSEGV, Segmentation fault.6.2. 原因就是智能指针未初始化未初始化的智能指针是可以调用成员函数的这个成员函数甚至可以申请内存只有在访问成员变量时才会崩溃。参考文献Linux中error while loading shared libraries错误解决办法_hankerbit的博客-CSDN博客解决 error while loading shared libraries: xxx.so.x_weixin_41666796的博客-CSDN博客gcc - Why is -marchnative used so rarely? - Stack Overflow
C++ 运行问题汇总
发布时间:2026/7/10 12:58:13
1. 找不到共享库1.1. 现象error while loading shared xxx.so1.2. 原因分析默认情况下编译器只会使用/lib和/usr/lib这两个目录下的库文件通常通过源码包进行安装时如果不指定--prefix会将库安装在/usr/local/lib目录下当运行程序需要链接动态库时提示找不到相关的.so库会报错。也就是说/usr/local/lib目录不在系统默认的库搜索目录中需要将目录加进去。1.3. 解决方法如果共享库文件安装到了/lib或/usr/lib目录下那么需执行一下ldconfig命令如果共享库文件安装到了/usr/local/lib(很多开源的共享库都会安装到该目录下)或其它非/lib或/usr/lib目录下,把新共享库目录加入到共享库配置文件/etc/ld.so.conf中。例如添加下面两行/usr/lib64 /opt/ros/kinetic/lib然后再执行ldconfig命令如果共享库文件安装到了其它非/lib或/usr/lib目录下但是又不想在/etc/ld.so.conf中加路径(或者是没有权限加路径).那可以export一个全局变量LD_LIBRARY_PATH然后运行程序的时候就会去这个目录中找共享库LD_LIBRARY_PATH的意思是告诉loader在哪些目录中可以找到共享库。可以设置多个搜索目录这些目录之间用冒号分隔开。比如安装了一个mysql到/usr/local/mysql目录下其中有一大堆库文件在/usr/local/mysql/lib下面则可以在.bashrc或.bash_profile或shell里加入以下语句即可export LD_LIBRARY_PATH/usr/local/mysql/lib:$LD_LIBRARY_PATH一般来讲这只是一种临时的解决方案在没有权限或临时需要的时候使用2. 无法获取内存2.1. 现象error reading variable: Cannot access memory at address2.2. 原因分析一般是因为使用了未分配内存的指针3. double free2.3. 现象double free or corruption (out)2.3. 原因分析cmake编译选项问题可能是编译时加了下面的选择而编译链接库时却没有加set(CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS} -marchnative)-marchnativeis a destructive flag. It makes the binary possible not compatible on a lot of hardware (basically any CPU that is not a direct descendent of the one used for compilation). It is simply too dangerous to enable this by default.Another important thing to consider is that-marchnatives main end use is optimization. The default optimization flag is-O0(no optimization) so it wouldnt make sense from this perspective either to enable it by default.-marchnative 是gccg编译器的编译选项开启后编译器也就是 gcc/g) 会自动检测电脑CPU型号根据内置的数据库查询该CPU型号支持何种增强指令集比如各版本的SSE AVX等等如果某个指令集可用在编译器编译、优化代码时会尝试“擅作主张”将它认为可以优化的操作使用这些指令集替代以期得到更快的执行效率。这么一看是皆大欢喜的事情但问题在于 SSE AVX这类指令集大多要求参与计算的操作数需要按照一定的格式在内存中存储比如常见的4字节对齐或者16字节对齐个别指令还要求某个操作数必须放置在特定的 CPU Cache里。如果只是单独编译一个文件这没有什么问题可在大部分应用场景中我们自己编译的程序需要连接到第三方库。这个时候问题就来了如果第三方库编译时没有启用-marchnative那么其变量都是按照编译器默认规则分配在内存中的如果此时咱们自己的程序启用了-marchnative那么涉及到可用增强指令集加速的变量则大概率是按照前面4字节对齐、16字节对齐等格式保存在内存中的。如果发生了函数的参数传递、函数调用等操作第三方库代码并不了解咱们已经使用了增强指令集加速还是会按照默认方式解析实参堆栈就会出现获取了错误参数的情况同时咱们自己写的程序也会出现尝试使用第三方库返回的非内存对齐的变量使得增强指令集无法正确寻址这些指令一般只能从4或者16等数字的倍数地址处获取数据从而产生内存非法访问。一般来说报错是Sgement fault但也正由于发生错误可能是数据指针不对、也可能是访问地址不对因此实际报错也会出现你遇到的double free的情况。许多的博客说将-marchnative去掉就可以不报错了我不认同。之所以有这个论断是 在Ubuntu下几乎所有使用apt-get这种二进制安装方法安装到第三方库为了兼容性一般提前编译时不打开-marchnative所以咱们自己的程序不打开-marchnative大部分情况下是可以确保编译通过的。但是如果自己手动编译安装了第三方库比如PCL编译时启用了-marchnative那么咱们自己的程序调用它时如果不加--marchnative 反而会报错。4. 同时链接了动态库与静态库4.1. 现象ERROR: something wrong with flag xxx in file xxx. One possibility: file xxx is being linked both statically and dynamically into this executable.4.2. 原因分析按照经验这是因为运行时的链接库路径中同时包含动态库和静态库修改LD_LIBRARY_PATH让它只包含动态库即可。5. 函数调用过程中变量值不同5.1. 现象定义了一个成员变量struct State { double time; Eigen::Quaterniond q; }该变量以const引用的方式传参进行函数调用时在函数调用前值是正常的进入函数内值就不正常了调用完返回后值又正常了。如果把其中的q去掉或者替换成Eigen::Vecotor3d类型就不会出这个问题。5.2. 原因分析因为上述的被调函数和调用它的函数处在不同的链接库中而这两个库在编译时使用了不同的编译选项这会导致Eigen::Quaterniond在内存解析时会有所有不同而调用时使用的又是const引用的方式进行传参所以会出此问题。5.3. 解决方法所有编译产出包括链接库和可执行文件都使用相同的编译选项6. 成员变量崩溃6.1. 现象通过智能指针调用类的成员函数很多功能都可以正常运行唯独崩溃在成员变量处。received signal SIGSEGV, Segmentation fault.6.2. 原因就是智能指针未初始化未初始化的智能指针是可以调用成员函数的这个成员函数甚至可以申请内存只有在访问成员变量时才会崩溃。参考文献Linux中error while loading shared libraries错误解决办法_hankerbit的博客-CSDN博客解决 error while loading shared libraries: xxx.so.x_weixin_41666796的博客-CSDN博客gcc - Why is -marchnative used so rarely? - Stack Overflow