必须用 delete[] 释放 new[] 分配的动态数组,否则导致未定义行为、内存泄漏或崩溃;需配对使用、释放后置空指针、禁止混用 malloc/free;推荐改用 std::vector 或 std::unique_ptr<T[]>。
![c++动态数组怎么用delete[]正确释放](https://img.php.cn/upload/article/001/221/864/179049343783072.png)
用 delete[] 释放动态数组,必须和 new[] 配对
如果你用 new int[10] 分配了数组,就必须用 delete[] ptr 释放,不能写成 delete ptr。后者只调用一次析构函数(对非类类型看似“能跑”,但行为未定义),对 std::string 或自定义类数组会导致严重内存泄漏或崩溃。
常见错误现象:double free or corruption (out)、程序随机崩溃、Valgrind 报告 “mismatched free() / delete / delete []”。
-
new[]和delete[]是一对原子操作:前者分配连续内存并调用每个元素的构造函数(如有),后者反向执行——逐个调用析构函数,再释放整块内存 - 编译器不检查配对关系,所以写错不会报错,只在运行时埋雷
- 对内置类型(如
int、char)漏掉[]可能“暂时没出事”,但属于未定义行为,换编译器或优化级别就可能翻车
释放后立即置空指针,避免重复释放
释放完不把指针设为 nullptr,后续若再次 delete[] ptr 就是重复释放,直接触发未定义行为。
使用场景:函数内部分配、异常路径、多次重分配等容易遗漏的地方。
立即学习“C++免费学习笔记(深入)”;
- 推荐写法:
int* arr = new int[100]; // ... 使用 delete[] arr; arr = nullptr;
- 如果指针是局部变量且不会再用,置空不是必须的;但如果是类成员或全局/静态变量,强烈建议置空
- 注意:置空不能防止“野指针”读取(
if (arr) { use(*arr); }仍可能崩),只是让重复delete[]更安全
别混用 malloc/free 和 new[]/delete[]
用 malloc 分配的内存,必须用 free 释放;用 new[] 分配的,必须用 delete[]。两者底层管理机制不同,交叉使用等于主动破坏堆状态。
典型错误:char* buf = (char*)malloc(1024); delete[] buf; —— 这不是“差不多”,而是必然崩溃或静默损坏。
-
new[]可能比malloc多写入数组长度信息(用于析构),delete[]会去读这个隐藏字段;而free完全不认这个格式 - 即使对象是 POD 类型(如
int),也不能混用:C++ 标准明确禁止 - 现代 C++ 应优先用
std::vector或std::unique_ptr<T[]>,彻底绕过手动管理
释放前确认指针非空且确实由 new[] 分配
传入 delete[] 的指针必须满足两个条件:非空、且由 new[] 返回。指向栈内存、文字常量区、或别的 new(非 new[])结果,都会立刻 UB。
容易被忽略的点:数组退化为指针后,类型信息丢失,编译器无法帮你验证来源。
- 例如:
int local[5]; int* p = local; delete[] p; // 错!栈内存不能 delete[]
- 又如:
const char* s = "hello"; delete[] s;—— 文字常量区不可释放 - 调试建议:在关键分配点加日志,或用 AddressSanitizer 检测非法释放
实际项目里最麻烦的不是语法记不住,而是跨函数、跨模块传递指针时,谁分配谁释放的契约模糊。一旦有人偷偷用 new 替代 new[],或者封装层悄悄把 new[] 结果转成 void* 再传出,delete[] 就成了定时炸弹。


















