nothrow版本new在内存不足时不抛异常而返回nullptr,需显式检查空指针;它不改变数组初始化行为,不支持带初始化器语法,且必须配对使用delete[]。

使用 new 的 nothrow 版本分配动态数组不会抛出异常
当系统内存不足时,普通 new 会抛出 std::bad_alloc 异常;而带 nothrow 的版本在失败时返回 nullptr,适合不想用异常处理逻辑的场景。但注意:它只影响分配是否抛异常,不改变数组本身的生命周期或初始化行为。
-
new (std::nothrow) int[100]返回int*,失败时为nullptr,不是int[]*或其他类型 - 数组元素仍按默认方式初始化(
int不初始化,std::string会调用默认构造函数) - 必须手动配对使用
delete[],不能用delete,否则未定义行为 - 不支持带初始化器的语法,例如
new (std::nothrow) int[3]{1,2,3}是非法的(C++11 起标准禁止)
常见错误:把 nothrow 当成“安全分配”就忽略空指针检查
很多人以为加了 nothrow 就万事大吉,其实只是把异常转成了空指针——如果忘了检查,后续解引用会直接崩溃。
- 错误写法:
int* p = new (std::nothrow) int[1000000]; p[0] = 42;—— 若分配失败,p是nullptr,p[0]触发段错误 - 正确做法:始终检查
if (p == nullptr) { /* 处理失败 */ } - 尤其在嵌入式或低内存环境,即使小数组(如
new (std::nothrow) char[4096])也可能失败
与 std::vector 和 malloc 的关键区别
new (std::nothrow) 是 C++ 原生机制,但它不提供容量管理、自动释放或异常安全保障,容易比错用。
组合式C++代码评审方案,融合静态分析、AI推理、多轮迭代评审和C++专项检查,适用于PR审查、增量代码审查、全项目评审和代码质量评分,触发词包括review cpp、cpp代码评审、C++review、代码审查。
-
std::vector内部也用new,但构造失败时仍会抛异常;若需无异常扩容,得自己捕获或用try_emplace等替代方案 -
malloc不调用构造函数,对 POD 类型可用,但对std::string等类类型无法正确初始化,且不兼容delete[] - 没有
nothrow对应的delete[]版本——释放空指针是安全的,但必须显式写delete[] p;,不能省略
实际项目中更推荐的替代方案
除非明确受限于异常禁用(如某些实时系统或游戏引擎模块),否则直接用 std::vector 更可靠。如果真要用裸指针 + nothrow,务必封装检查逻辑。
立即学习“C++免费学习笔记(深入)”;
- 简单封装示例:
template<typename T> T* safe_new_array(size_t n) { T* p = new (std::nothrow) T[n]; if (!p) std::abort(); // 或记录日志、返回错误码 return p; } - 现代 C++ 中,
std::unique_ptr<t></t>可自动管理new (std::nothrow)分配的数组,避免忘记delete[] - 注意:GCC/Clang 在
-fno-exceptions下,普通new也会退化为nothrow行为,但标准未强制要求,不可依赖
真正难的不是写对那一行 new (std::nothrow),而是确保每个分支都检查了 nullptr,且所有路径都正确配对 delete[]——漏掉一次,就是运行时崩溃的伏笔。

















