C++的std::bad_alloc异常在什么内存分配失败时会被触发? (异常处理机制)

5次阅读

std::bad_alloc仅在标准库明确要求抛异常的分配操作中抛出:new表达式(无nothrow)、vector/String::reserve、make_unique/make_shared及显式调用operator new(非nothrow)失败时;malloc等返回空指针,不抛此异常。

C++的std::bad_alloc异常在什么内存分配失败时会被触发? (异常处理机制)

std::bad_alloc 在哪些分配操作里会抛出?

它只在 c++ 标准库明确要求“分配失败时必须抛异常”的场景下触发,不是所有 malloc 失败都会变成 std::bad_alloc。关键看调用的是哪一层接口

  • new 表达式(不带 nothrow)——最常见来源,比如 new int[1000000000] 超出可用内存时
  • std::vector::reserve()std::string::reserve() 等容器预分配内部缓冲区失败时
  • std::make_unique / std::make_shared 底层调用 new 失败时
  • 显式调用 operator new(非 operator new nothrow)失败时

注意:mallocreallocoperator new(std::nothrow) 这些失败都返回空指针或 nullptr,**不会**抛 std::bad_alloc

为什么有时候 OOM 了却没抛 std::bad_alloc?

因为分配器行为和编译器实现有关,尤其在资源耗尽边界上表现不一致:

  • linux 默认启用 overcommit(/proc/sys/vm/overcommit_memory = 1),new 可能成功返回地址,但第一次真正写入时触发 Segmentation fault 或被 OOM Killer 杀掉进程——这时根本没机会走到 std::bad_alloc
  • 某些嵌入式 STL 实现或自定义分配器可能禁用异常,把 new 降级为返回 nullptr(需确认是否定义了 _GLIBCXX_USE_CXX11_ABI 和异常开关)
  • 链接时用了 -fno-exceptions,所有 throw 都被编译器忽略,程序直接 abort 或未定义行为

所以不能假设“内存不够 → 一定 catchstd::bad_alloc”,得结合系统策略和编译选项一起看。

立即学习C++免费学习笔记(深入)”;

捕获 std::bad_alloc 的实际建议

它不是用来兜底“程序快崩了”的万能异常,而是用于局部可控的资源申请失败处理:

  • 只在明确知道某次分配可能失败、且有替代路径时才 try/catch,比如尝试分配大缓存失败后切回流式处理
  • 不要在 main() 外层无差别 catch(…),std::bad_alloc 不代表可恢复,更不代表其他异常也能这么搞
  • 避免在析构函数里 new —— 析构中抛 std::bad_alloc 会导致 std::terminate,因为展开期间再抛异常是未定义行为
  • 如果用 std::vector::resize(),注意它内部先 allocate 再 construct,allocate 失败才抛 std::bad_alloc;construct 失败则抛构造函数自己的异常

示例:

try {     auto buf = std::make_unique(1_GiB); } catch (const std::bad_alloc& e) {     // 这里能拿到的只是分配失败信号,不代表整个进程还有多少余量     log("fallback to mmap or disk buffer"); }

和 operator new(nothrow) 混用时的坑

混用带异常和不带异常的分配方式容易误判失败原因:

  • new (std::nothrow) T 返回 nullptr,而 new Tstd::bad_alloc —— 二者语义不同,不能靠是否抛异常来统一判断“内存是否紧张”
  • 自定义全局 operator new 若没实现 nothrow 版本,或实现里忘了 throw,会导致行为不一致
  • 第三方库(如 Eigen、opencv)内部可能用 nothrow 分配,你 catch std::bad_alloc 完全捕不到它们的失败

真要监控内存压力,得靠 mallinfomalloc_stats 或 cgroup memory limit 配合信号(SIGUSR1 等),而不是依赖异常抛出时机。

text=ZqhQzanResources