0

0

c++如何使用std-bad-alloc处理内存不足_c++异常监控【要点】

尼克

尼克

发布时间:2026-03-16 21:25:31

|

508人浏览过

|

来源于php中文网

原创

std::bad_alloc只是内存分配失败的信号而非解决方案,无法自动恢复内存;应优先使用new(std::nothrow)主动检测,结合资源生命周期管理与峰值控制来预防。

c++如何使用std-bad-alloc处理内存不足_c++异常监控【要点】

std::bad_alloc 是什么,它真能帮你“处理”内存不足吗

不能。它只是个信号,不是解决方案。std::bad_allocnew 表达式在无法分配请求内存时抛出的异常,但它不告诉你缺多少、哪块没释放、能不能降级——只说明“现在 malloc 失败了”。你 catch 它,不代表问题消失;不 catch,程序直接终止(默认 terminate)。

常见错误现象:terminate called after throwing an instance of 'std::bad_alloc',但堆栈里看不到 new 调用,因为异常可能被层层上抛后才崩溃;或者 catch 住后继续运行,结果后续 operator new 又崩,陷入重复失败。

  • 别指望靠 catch std::bad_alloc 自动恢复内存——C++ 不提供内存回收魔法
  • 它不区分“临时性OOM”和“彻底耗尽”,也不触发 GC(C++ 没 GC)
  • 在嵌入式或实时系统中,抛异常本身可能不可用(编译器禁用异常),此时 new(std::nothrow) 才是实际入口

怎么安全地检测并响应内存分配失败

核心原则:主动防御,而非被动捕获。优先用 new(std::nothrow) 替代裸 new,把异常路径转为显式判空。

使用场景:构造关键对象前、加载大资源(如图像帧、模型权重)、容器扩容(std::vector::reserve)。

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

<pre class="brush:php;toolbar:false;">auto ptr = new(std::nothrow) int[1000000];
if (!ptr) {
    log_error("failed to allocate 1M ints");
    fallback_to_disk_buffer(); // 或降级逻辑
    return;
}
// 正常使用 ptr...
  • std::nothrow 是唯一标准方式绕过异常机制,返回 <code>nullptr 而非抛 std::bad_alloc
  • std::vector::reserve 可能抛 std::bad_alloc,但 push_back 不会——它内部用 new(std::nothrow) + 重试或 throw,行为取决于实现
  • 自定义分配器(如池式分配器)可完全屏蔽 std::bad_alloc,但需确保其 allocate 方法不抛异常(否则违反 Allocator 要求)

全局 new-handler 能做什么,为什么多数人不该碰

std::set_new_handler 允许注册一个函数,在每次 new 失败前被调用一次。但它不是“重试钩子”,而是“最后通牒”:你必须在这函数里做三件事之一——抛异常、std::abort、或让后续 new 成功(比如释放缓存)。

会译·对照式翻译
会译·对照式翻译

会译是一款AI智能翻译浏览器插件,支持多语种对照式翻译

下载

容易踩的坑:new-handler 被调用时,堆很可能已处于碎片化临界状态,任何额外分配(包括 std::string 构造、日志输出)都可能再次触发 handler,导致无限递归崩溃。

  • handler 函数必须是 noexcept,且不能调用任何可能分配内存的标准库函数
  • 典型可用操作:调用 std::malloc(不走 operator new)、清空 LRU 缓存、std::quick_exit
  • 多线程下 handler 是全局的,不同线程的 new 失败都会进同一个函数,需自己加锁或避免共享状态

真正有效的内存不足应对策略

异常监控只是表象,根因在资源生命周期管理。与其等 std::bad_alloc,不如从源头控制峰值内存。

性能影响:频繁触发 std::bad_alloc 意味着设计缺陷——比如未限制 std::vector 的最大容量、读取文件不流式处理、缓存无淘汰策略。

  • 对大对象,优先用 std::unique_ptr + make_unique,避免栈溢出或中间状态泄漏
  • std::pmr::polymorphic_allocator 隔离高风险模块的内存域,防止一个模块吃光全部堆
  • Linux 下可检查 /proc/self/statusVmRSS,结合 mmap(MAP_NORESERVE) 预留地址空间但延迟物理页分配

最常被忽略的一点:std::bad_alloc 往往不是突然发生的,而是某次 vector::resizestring::append 触发的连锁反应——查日志时要倒着看前 10 次分配,而不是只盯着崩溃那一行。

相关文章

c++速学教程(入门到精通)
c++速学教程(入门到精通)

c++怎么学习?c++怎么入门?c++在哪学?c++怎么学才快?不用担心,这里为大家提供了c++速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热门AI工具

更多
DeepSeek
DeepSeek

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

豆包大模型
豆包大模型

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

WorkBuddy
WorkBuddy

腾讯云推出的AI原生桌面智能体工作台

腾讯元宝
腾讯元宝

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

文心一言
文心一言

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

讯飞写作
讯飞写作

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

即梦AI
即梦AI

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

ChatGPT
ChatGPT

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

相关专题

更多
string转int
string转int

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

1071

2023.08.02

堆和栈的区别
堆和栈的区别

堆和栈的区别:1、内存分配方式不同;2、大小不同;3、数据访问方式不同;4、数据的生命周期。本专题为大家提供堆和栈的区别的相关的文章、下载、课程内容,供大家免费下载体验。

448

2023.07.18

堆和栈区别
堆和栈区别

堆(Heap)和栈(Stack)是计算机中两种常见的内存分配机制。它们在内存管理的方式、分配方式以及使用场景上有很大的区别。本文将详细介绍堆和栈的特点、区别以及各自的使用场景。php中文网给大家带来了相关的教程以及文章欢迎大家前来学习阅读。

606

2023.08.10

堆和栈的区别
堆和栈的区别

堆和栈的区别:1、内存分配方式不同;2、大小不同;3、数据访问方式不同;4、数据的生命周期。本专题为大家提供堆和栈的区别的相关的文章、下载、课程内容,供大家免费下载体验。

448

2023.07.18

堆和栈区别
堆和栈区别

堆(Heap)和栈(Stack)是计算机中两种常见的内存分配机制。它们在内存管理的方式、分配方式以及使用场景上有很大的区别。本文将详细介绍堆和栈的特点、区别以及各自的使用场景。php中文网给大家带来了相关的教程以及文章欢迎大家前来学习阅读。

606

2023.08.10

线程和进程的区别
线程和进程的区别

线程和进程的区别:线程是进程的一部分,用于实现并发和并行操作,而线程共享进程的资源,通信更方便快捷,切换开销较小。本专题为大家提供线程和进程区别相关的各种文章、以及下载和课程。

786

2023.08.10

Python 多线程与异步编程实战
Python 多线程与异步编程实战

本专题系统讲解 Python 多线程与异步编程的核心概念与实战技巧,包括 threading 模块基础、线程同步机制、GIL 原理、asyncio 异步任务管理、协程与事件循环、任务调度与异常处理。通过实战示例,帮助学习者掌握 如何构建高性能、多任务并发的 Python 应用。

379

2025.12.24

java多线程相关教程合集
java多线程相关教程合集

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

33

2026.01.21

chatgpt使用指南
chatgpt使用指南

本专题整合了chatgpt使用教程、新手使用说明等等相关内容,阅读专题下面的文章了解更多详细内容。

0

2026.03.16

热门下载

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

精品课程

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

共94课时 | 11.5万人学习

C 教程
C 教程

共75课时 | 5.5万人学习

C++教程
C++教程

共115课时 | 22.2万人学习

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

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