new 分配失败默认抛 std::bad_alloc 异常导致程序终止;应使用 new (std::nothrow) 获取 nullptr,嵌入式中必须如此;new[] 必须配 delete[],否则类类型析构不全;new t() 值初始化,new t 不初始化;malloc/free 与 new/delete 绝对不可混用。

new 分配失败时程序直接崩溃?先检查 std::nothrow
默认情况下,new 在内存不足时抛出 std::bad_alloc 异常,没加 try/catch 就会终止程序。这不是“没分配成功”,是直接炸了。
- 如果想避免异常,改用
new (std::nothrow) int[1000]—— 分配失败返回nullptr,不抛异常 - 但注意:
std::nothrow只影响这次调用,不影响后续new行为 - 在嵌入式或硬实时场景中,异常机制可能被禁用(编译器选项如
-fno-exceptions),此时必须用std::nothrow,否则链接会失败
delete [] 忘了加中括号?对象析构只调一次
用 new[] 分配的数组,必须用 delete[] 释放。写成 delete 看似能编译通过,但后果严重:
- 对内置类型(如
int、double)可能暂时没表现,但属于未定义行为 - 对类类型,只有第一个元素的析构函数被调用,其余对象的析构函数被跳过 —— 资源泄漏(文件句柄、内存、锁等)大概率发生
- MSVC 和 GCC 在 debug 模式下有时会触发断言或报错,但 release 下静默失效
new 分配的内存不初始化?看类型和语法
new T 和 new T() 效果不同,尤其对 POD 类型:
-
new int→ 值未定义(栈上变量同理) -
new int()→ 值为0(值初始化) -
new std::string→ 调用默认构造函数,内容为空字符串 -
new MyClass→ 调用默认构造函数;若无默认构造且未显式初始化,编译失败
别依赖“编译器帮你清零”——除非你写了 () 或类型自带构造逻辑。
立即学习“C++免费学习笔记(深入)”;
malloc/free 和 new/delete 混用?绝对不行
它们底层可能走不同堆管理器,也可能调用不同的内存对齐或调试钩子:
-
int* p = (int*)malloc(100); delete p;→ 未定义行为,常见 crash 或堆损坏 -
int* p = new int[10]; free(p);→ 同样未定义,析构函数不会被调,内存回收路径错乱 - 即使
sizeof(int)相同、看起来“都是整数指针”,也不能跨体系混用
new/delete 是 C++ 运行时的一部分,负责构造/析构 + 内存分配;malloc/free 是 C 标准库函数,只管内存块。两者语义不兼容,边界不能模糊。
C++ 动态分配真正难的不是语法,是生命周期归属是否清晰、释放时机是否确定、以及有没有人悄悄把 new 出来的指针传给了 C 接口或裸指针容器。这些地方一漏,问题往往延迟暴露。











