new默认抛std::bad_alloc异常而非返回nullptr,须用try/catch捕获;若需nullptr语义,应使用new(std::nothrow)并配合if检查;malloc则必须检查返回值是否为nullptr;推荐优先使用std::vector以规避手动内存管理风险。

new 分配失败时抛出 std::bad_alloc 异常
现代 C++ 中,new 默认在内存不足时**不返回 nullptr,而是抛出 std::bad_alloc 异常**。这是最容易被误判的一点——很多人还沿用 C 风格的 if (ptr == nullptr) 检查,结果程序直接崩溃而没走判断分支。
- 必须用
try/catch捕获std::bad_alloc,不能靠空指针检查 - 如果想让
new返回nullptr而非抛异常,需显式使用new (std::nothrow) -
std::nothrow版本是唯一能配合if (ptr == nullptr)安全使用的场景
使用 new (std::nothrow) 获取 nullptr 失败信号
当你需要手动检查分配结果(比如嵌入式、实时系统或已有错误处理框架),new (std::nothrow) 是标准且安全的选择。它不抛异常,分配失败时返回 nullptr。
int* arr = new (std::nothrow) int[1000000];
if (arr == nullptr) {
// 处理分配失败:日志、降级、退出等
return;
}
// 使用 arr...
delete[] arr;
-
std::nothrow是定义在<new></new>头文件中的常量,需#include <new></new> - 注意匹配:用
new (std::nothrow)分配,就用delete[]释放,不要混用delete - 该方式牺牲了异常语义的清晰性,但换来确定性的控制流,适合对异常敏感的环境
malloc 分配后检查返回值不等于 nullptr
如果你混用 C 风格内存管理(例如调用 malloc、calloc),则必须检查返回值——malloc 在失败时明确返回 nullptr,不会抛异常。
组合式C++代码评审方案,融合静态分析、AI推理、多轮迭代评审和C++专项检查,适用于PR审查、增量代码审查、全项目评审和代码质量评分,触发词包括review cpp、cpp代码评审、C++review、代码审查。
int* arr = static_cast<int>(malloc(1000000 * sizeof(int)));
if (arr == nullptr) {
// 分配失败
return;
}
// 使用 arr...
free(arr);</int>
-
malloc不调用构造函数,适用于 POD 类型;若需构造对象,应优先用new - 务必用
free释放malloc分配的内存,混用delete[]是未定义行为 - 注意
sizeof计算:避免写成malloc(1000000 * sizeof(int*))这类低级错误
std::vector 替代裸数组,规避手动检查
绝大多数场景下,真正需要“检查分配是否成功”的诉求,本质是想避免程序因 OOM 崩溃。这时最稳妥的做法不是自己检查,而是用 std::vector——它的构造和 resize 在失败时也抛 std::bad_alloc,但封装了内存管理细节,减少出错面。
try {
std::vector<int> vec(1000000);
// 使用 vec
} catch (const std::bad_alloc& e) {
// 统一处理内存不足
}</int>
-
std::vector的异常安全性比裸指针高得多:即使中途抛异常,析构函数会自动清理 - 不需要手动
delete[],避免忘记释放或重复释放 - 如果真要检查容量是否满足,可用
vec.capacity(),但注意这反映的是已分配空间,不是分配是否成功
真正容易被忽略的点是:异常是否被全局捕获、std::set_new_handler 是否被设置、以及多线程环境下分配器状态是否一致。这些不在基础检查范围内,但一旦出现偶发失败,问题往往卡在这里。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!










