0

0

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

尼克

尼克

发布时间:2026-02-11 09:31:23

|

302人浏览过

|

来源于php中文网

原创

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 或未定义行为

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

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

创客贴设计
创客贴设计

创客贴设计,一款智能在线设计工具,设计不求人,AI助你零基础完成专业设计!

下载

捕获 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 等),而不是依赖异常抛出时机。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
string转int
string转int

在编程中,我们经常会遇到需要将字符串(str)转换为整数(int)的情况。这可能是因为我们需要对字符串进行数值计算,或者需要将用户输入的字符串转换为整数进行处理。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

688

2023.08.02

string转int
string转int

在编程中,我们经常会遇到需要将字符串(str)转换为整数(int)的情况。这可能是因为我们需要对字符串进行数值计算,或者需要将用户输入的字符串转换为整数进行处理。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

688

2023.08.02

int占多少字节
int占多少字节

int占4个字节,意味着一个int变量可以存储范围在-2,147,483,648到2,147,483,647之间的整数值,在某些情况下也可能是2个字节或8个字节,int是一种常用的数据类型,用于表示整数,需要根据具体情况选择合适的数据类型,以确保程序的正确性和性能。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

555

2024.08.29

c++怎么把double转成int
c++怎么把double转成int

本专题整合了 c++ double相关教程,阅读专题下面的文章了解更多详细内容。

193

2025.08.29

C++中int的含义
C++中int的含义

本专题整合了C++中int相关内容,阅读专题下面的文章了解更多详细内容。

206

2025.08.29

硬盘接口类型介绍
硬盘接口类型介绍

硬盘接口类型有IDE、SATA、SCSI、Fibre Channel、USB、eSATA、mSATA、PCIe等等。详细介绍:1、IDE接口是一种并行接口,主要用于连接硬盘和光驱等设备,它主要有两种类型:ATA和ATAPI,IDE接口已经逐渐被SATA接口;2、SATA接口是一种串行接口,相较于IDE接口,它具有更高的传输速度、更低的功耗和更小的体积;3、SCSI接口等等。

1368

2023.10.19

PHP接口编写教程
PHP接口编写教程

本专题整合了PHP接口编写教程,阅读专题下面的文章了解更多详细内容。

318

2025.10.17

php8.4实现接口限流的教程
php8.4实现接口限流的教程

PHP8.4本身不内置限流功能,需借助Redis(令牌桶)或Swoole(漏桶)实现;文件锁因I/O瓶颈、无跨机共享、秒级精度等缺陷不适用高并发场景。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2202

2025.12.29

包子漫画网页版入口与全集阅读指南_正版免费漫画快速访问方法
包子漫画网页版入口与全集阅读指南_正版免费漫画快速访问方法

本专题汇总了包子漫画官网和网页版入口,提供最新章节抢先看方法、正版免费阅读指南,以及稳定访问方式,帮助用户快速直达包子漫画页面,无广告畅享全集漫画内容。

50

2026.02.10

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
C# 教程
C# 教程

共94课时 | 9.1万人学习

C 教程
C 教程

共75课时 | 4.6万人学习

C++教程
C++教程

共115课时 | 17万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号