You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

RHEL7下GCC8.2编译C++代码出现operator delete链接错误求助

解决GCC 8.2编译C++代码时operator delete(void*, unsigned long)未定义引用的问题

我之前碰到好几个开发者在RHEL7上升级GCC后遇到这个问题,正好可以给你梳理下原因和解决办法:

问题根源

GCC 5.x及以后的版本中,libstdc++(GNU的C标准库)引入了带unsigned long参数的operator delete重载,这个重载是为了支持"大小感知"的内存释放优化。而你之前用的GCC 4.8配套的是旧版libstdc,只提供了不带大小参数的operator delete(void*)。

RHEL7默认的系统标准库是和GCC 4.8绑定的,当你用GCC 8.2编译代码时,编译器会生成调用新版operator delete(void*, unsigned long)的指令,但链接阶段还是去找系统旧版的libstdc++,自然找不到这个符号,就报了未定义引用的错误。

可行的解决方案

1. 强制链接GCC 8.2自带的libstdc++

这是最推荐的方案,让编译和链接用同一版本的标准库:

  • 如果是静态链接,编译时加上-static-libstdc++参数
  • 如果是动态链接,需要指定GCC 8.2安装目录下的库路径,比如假设你的GCC 8.2装在/opt/gcc-8.2,编译命令可以改成:
    g++ -std=c++17 your_code.cpp -L/opt/gcc-8.2/lib64 -Wl,-rpath=/opt/gcc-8.2/lib64
    
    -L告诉编译器去哪里找库,-Wl,-rpath则指定程序运行时的库搜索路径。

2. 降级C++编译标准

GCC 8.2默认会用较新的C标准(比如C17),如果你不需要新特性,可以指定和GCC 4.8一致的标准,让编译器生成兼容旧版libstdc++的代码:

g++ -std=c++11 your_code.cpp

这样编译器会调用旧版的operator delete(void*),就能和系统库兼容了。

3. 显式补充缺失的operator delete重载

如果上面两种方案都不适合,你可以在代码中手动实现这个重载,让它调用旧版的delete:

#include <cstdlib>

void operator delete(void* ptr, unsigned long size) noexcept {
    // 直接转发到旧版的无参数delete
    operator delete(ptr);
}

这个方法能快速解决链接错误,但要注意:如果你的代码依赖新版delete的大小优化逻辑,这种转发可能会丢失相关优化,所以只适合临时应急或者确认不需要优化的场景。

补充说明

为什么GCC 4.8编译没问题?因为GCC 4.8的编译器只会生成调用operator delete(void*)的代码,而RHEL7系统的libstdc++正好提供这个符号,所以链接完全正常。

内容的提问来源于stack exchange,提问作者mmm

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.13 08:20:13