g++编译报错:undefined reference to `std::__throw_bad_array_new_length()`求助
解决g++链接错误:
undefined reference to std::__throw_bad_array_new_length() 问题背景
我正在用C++实现kD-Tree和kNN算法,使用MNIST数据集。编译命令为:
g++ -o main main.cpp kDTree.cpp Dataset.o -I . -std=c++11
g++版本为10.3。编译时出现如下链接错误:
E:\C_plus_code\init> g++ -o main main.cpp kDTree.cpp Dataset.o -I . -std=c++11 C:/TDM-GCC-64/bin/../lib/gcc/x86_64-w64-mingw32/10.3.0/../../../../x86_64-w64-mingw32/bin/ld.exe: Dataset.o:Dataset.cpp:(.text$_ZNSt15__new_allocatorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEE8allocateEyPKv[_ZNSt15__new_allocatorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEE8allocateEyPKv]+0x4a): undefined reference to `std::__throw_bad_array_new_length()' C:/TDM-GCC-64/bin/../lib/gcc/x86_64-w64-mingw32/10.3.0/../../../../x86_64-w64-mingw32/bin/ld.exe: Dataset.o:Dataset.cpp:(.text$_ZNSt15__new_allocatorISt10_List_nodeIiEE8allocateEyPKv[_ZNSt15__new_allocatorISt10_List_nodeIiEE8allocateEyPKv]+0x4a): undefined reference to `std::__throw_bad_array_new_length()' C:/TDM-GCC-64/bin/../lib/gcc/x86_64-w64-mingw32/10.3.0/../../../../x86_64-w64-mingw32/bin/ld.exe: Dataset.o:Dataset.cpp:(.text$_ZNSt15__new_allocatorISt10_List_nodeINSt7__cxx114listIiSaIiEEEEE8allocateEyPKv[_ZNSt15__new_allocatorISt10_List_nodeINSt7__cxx114listIiSaIiEEEEE8allocateEyPKv]+0x4a): undefined reference to `std::__throw_bad_array_new_length()' collect2.exe: error: ld returned 1 exit status
请问该如何解决?是否需要升级g++版本?
问题本质
这个错误是编译与链接阶段的标准库ABI(应用二进制接口)不匹配导致的:现有Dataset.o文件是用不同编译选项或g++版本生成的,它依赖的标准库符号和当前链接时使用的标准库实现不一致,从而出现未定义引用。
解决步骤
1. 重新编译Dataset.cpp,统一编译参数
不要直接使用已有的Dataset.o,用和主程序完全一致的参数重新编译:
g++ -c Dataset.cpp -I . -std=c++11 -o Dataset.o
再执行原链接命令:
g++ -o main main.cpp kDTree.cpp Dataset.o -I . -std=c++11
这是最有效的解决方法——旧的Dataset.o可能是用默认C标准(如C98)或不同ABI编译的,重新编译能保证所有目标文件的ABI统一。
2. 显式指定C++11 ABI选项
部分TDM-GCC版本默认使用旧ABI,可在编译时强制指定C++11兼容的ABI:
编译所有源文件时添加-D_GLIBCXX_USE_CXX11_ABI=1参数:
# 编译所有源文件 g++ -c Dataset.cpp -I . -std=c++11 -D_GLIBCXX_USE_CXX11_ABI=1 -o Dataset.o g++ -c kDTree.cpp -I . -std=c++11 -D_GLIBCXX_USE_CXX11_ABI=1 -o kDTree.o g++ -c main.cpp -I . -std=c++11 -D_GLIBCXX_USE_CXX11_ABI=1 -o main.o # 链接生成可执行文件 g++ -o main main.o kDTree.o Dataset.o -std=c++11
3. 无需升级g++版本
g10.3完全支持C11及更高标准,这个错误并非版本不足导致,因此不需要急于升级。只有当上述方法都无效时,再考虑更新TDM-GCC到最新稳定版(如12.x系列)。
4. 检查代码中的数组分配逻辑
虽然错误出现在链接阶段,但也可能是代码中存在非法数组大小分配(如负数、超出系统限制的数值),触发标准库抛出bad_array_new_length异常,进而因ABI不匹配导致符号找不到。可检查Dataset.cpp中new数组的代码,确保分配大小为合法正整数。
内容的提问来源于stack exchange,提问作者hoango27
相关产品推荐
相关产品推荐

