new[] 和 delete[] 必须严格配对使用,混用会导致未定义行为;推荐用 std::vector 替代裸 new[],或用 std::unique_ptr<T[]> 确保自动调用 delete[]。

new[] 和 delete[] 必须严格配对使用
用 new[] 分配的数组,必须用 delete[] 释放;用 new 分配的单个对象,必须用 delete 释放。混用会导致未定义行为:部分内存不被析构、堆元数据损坏、后续分配失败,甚至看似“没泄漏”实则已埋雷。
-
delete作用于new[]分配的指针 → 只调用首个元素的析构函数,其余元素内存未释放,且堆管理器可能丢失该块内存的长度信息 -
delete[]作用于new分配的单个对象 → 行为未定义,多数实现会崩溃或静默出错 - 编译器不检查配对关系,错误只在运行时暴露,且不一定立即显现
用 std::vector 替代裸 new[] 是最安全的选择
绝大多数场景下,std::vector 不仅语义清晰、异常安全,还能自动管理内存生命周期,彻底规避手动配对失误。它内部使用 new[]/delete[],但你完全不用碰这些细节。
- 替代
int* arr = new int[n];→ 直接写std::vector<int> arr(n);</int> - 需要动态扩容?
arr.push_back(x)比反复new[]+memcpy+delete[]更可靠 - 传参、返回、异常抛出时,
vector自动拷贝/移动,不会因提前返回而漏释放 - 若需兼容 C 接口(如传递给
extern "C"函数),可用arr.data()获取原始指针,但所有权仍在 vector 手中
必须用裸指针时,优先封装成 RAII 类型(如 unique_ptr)
如果因 ABI、性能或遗留接口等原因非用 new[] 不可,绝不要裸存指针。用 std::unique_ptr<t></t> 能保证离开作用域时自动调用 delete[],且禁止拷贝、支持移动,比手写类更轻量、更标准。
组合式C++代码评审方案,融合静态分析、AI推理、多轮迭代评审和C++专项检查,适用于PR审查、增量代码审查、全项目评审和代码质量评分,触发词包括review cpp、cpp代码评审、C++review、代码审查。
- 正确写法:
auto arr = std::make_unique<int>(1024);</int>—— 构造即拥有,析构即释放 - 不能写
std::unique_ptr<int> p(new int[1024]);</int>,这会触发delete而非delete[],导致泄漏 - 若需自定义删除器(如用
malloc/free),可显式传入std::default_delete<int></int>或 lambda,但通常没必要
容器里存裸指针是高危操作,必须显式清理
像 std::vector<int></int> 这类容器只管理指针本身,不管理指针指向的内存。清空容器(clear()、erase()、析构)不会自动 delete 元素所指对象 —— 这是开发者最容易忽略的“假安全”陷阱。
立即学习“C++免费学习笔记(深入)”;
- 错误示范:
vec.push_back(new int(42)); vec.clear();→ 内存泄漏 - 正确做法:遍历并
delete每个指针,再clear();或改用std::vector<:unique_ptr>></:unique_ptr> - 更推荐直接存储值类型(
std::vector<int></int>)或智能指针,避免裸指针在容器中游荡
真正难防的不是“忘了删”,而是“以为删了其实没删对”——比如 delete 代替 delete[],或容器 clear() 后误以为资源已释放。现代 C++ 的解法很明确:能用 std::vector 就别碰 new[];非碰不可,就用 std::unique_ptr<T[]> 把它锁死在 RAII 里。

















