new失败时抛std::bad_alloc而非返回nullptr,因c++默认使用异常版本new;未捕获会导致程序abort,stl容器操作同样可能触发,需在分配路径全程try-catch并妥善降级。

new 失败时为什么抛 std::bad_alloc 而不是返回 nullptr
因为 C++ 默认使用的是「抛异常版本」的 new,它在分配失败时不会静默返回 nullptr,而是直接抛出 std::bad_alloc。这和 C 的 malloc 行为完全不同,也容易让刚转 C++ 的人措手不及——没写 try 就崩溃了。
常见错误现象:terminate called after throwing an instance of 'std::bad_alloc',程序直接 abort,连堆栈都来不及打印。
- 除非显式调用
new(std::nothrow),否则所有裸new都是异常语义 -
std::vector::reserve()、std::string::resize()等内部调用 new 的操作,同样可能抛std::bad_alloc - 即使你没写
new,STL 容器扩容也可能触发它——别以为只有自己手动 new 才要管
捕获 std::bad_alloc 的正确姿势
不能只在 new 附近 try-catch,得覆盖整个可能触发分配的路径。比如构造一个含 vector 成员的类对象,构造函数里 vector 自动分配内存,异常就发生在初始化列表阶段。
实操建议:
- 用
try { ... } catch (const std::bad_alloc& e) { ... },不要捕获非 const 引用或值(避免切片) - catch 块里别再 new —— 你已经处于内存紧张状态,二次分配大概率再崩
- 优先做清理、日志、降级(如切到预分配缓冲区),而不是“重试”
- 如果是在库函数或回调里,确保异常能透出或转成错误码(取决于接口契约)
示例:
组合式C++代码评审方案,融合静态分析、AI推理、多轮迭代评审和C++专项检查,适用于PR审查、增量代码审查、全项目评审和代码质量评分,触发词包括review cpp、cpp代码评审、C++review、代码审查。
try {
std::vector<int> v(1024 * 1024 * 1024); // 请求 4GB
} catch (const std::bad_alloc& e) {
std::cerr <h3>用 <code>new(std::nothrow)</code> 替代异常?什么场景适合</h3>
<p>适合对异常敏感、无法/不愿引入异常处理机制的环境,比如嵌入式、实时系统、C 接口封装层。</p>
<p>但要注意:</p>
<ul>
<li>
<code>new(std::nothrow)</code> 返回 <code>nullptr</code>,必须每处都判空——漏一个就 UB</li>
<li>它只影响本次 new,不改变后续 STL 分配行为(<code>std::vector</code> 内部仍用 throw 版本)</li>
<li>编译器可能优化掉部分判空逻辑(尤其 Release 模式),静态分析工具比运行时更依赖人工检查</li>
<li>和 RAII 不天然兼容:智能指针构造时仍会 throw,不能靠 nothrow new 绕过</li>
</ul>
<p>典型用法:</p>
<pre class="brush:php;toolbar:false;">int* p = new(std::nothrow) int[1000000];
if (!p) {
log_error("allocation failed");
return -1; // 或其他错误传播方式
}
真正防住 OOM:从设计上减少动态分配依赖
处理 std::bad_alloc 是事后补救,真正健壮的系统得提前压分配量。很多看似“必须 new”的地方其实有替代方案。
- 用栈数组或
std::array替代小规模new[](比如长度 ≤ 1024) - 预分配池:对频繁创建销毁的小对象,用
boost::pool或自定义 freelist - 限制容器增长:
vector::reserve()配合容量检查,避免隐式翻倍扩容 - 改用 arena/slab 分配器(如
absl::InlinedVector、llvm::SmallVector)——它们优先用栈空间,超限时才 fall back 到 heap
最容易被忽略的一点:std::string 和 std::vector 的 move 构造函数不抛异常,但 copy 构造可能触发分配。传参时多用 const std::string& 或 std::string&&,少无脑 copy。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!










