delete后必须置nullptr,否则指针成悬垂指针;new[]须配delete[];禁对栈/全局内存delete;优先用智能指针或vector规避手动管理。

delete 之后必须置 nullptr
不置空的指针在 delete 后变成悬垂指针(dangling pointer),再次解引用或 delete 会触发未定义行为,常见表现为程序崩溃或静默数据损坏。C++ 标准不保证 delete 后指针值归零,它只是释放所指向内存,指针变量本身仍保存原地址。
-
delete ptr;只释放内存,ptr值不变,仍指向已回收区域 - 必须手动写
ptr = nullptr;,后续if (ptr)或二次delete才能安全跳过 - 若指针是类成员,建议在析构函数末尾统一置空;局部指针可在
delete后立即置空
new[] 必须配对使用 delete[]
用 new[] 分配的数组,必须用 delete[] 释放,否则仅调用第一个元素的析构函数(对 class 类型)且内存释放行为未定义。编译器通常无法在编译期检查这个错误,运行时可能崩溃或泄漏。
-
int* arr = new int[10];→ 必须用delete[] arr;,不是delete arr; -
std::string* strs = new std::string[5];→delete[] strs;否则其余 4 个对象的析构函数不被调用 - 现代 C++ 中优先用
std::vector或std::array,彻底规避手动配对问题
避免重复 delete 或释放栈/全局内存
重复 delete 是最常导致段错误的内存操作之一;而对非堆内存(如栈变量地址、字面量、全局数组)调用 delete 同样触发未定义行为。
- 不要对
&x(栈变量地址)、"hello"(字符串字面量)、static int buf[100];调用delete - 共享指针场景下,确认所有权归属——多个指针指向同一块堆内存时,只允许一个负责
delete - 调试时可临时启用 AddressSanitizer(
-fsanitize=address),它能捕获重复释放和释放栈内存等错误
优先用智能指针替代裸指针
裸指针的生命周期管理完全靠人工,极易出错;std::unique_ptr 和 std::shared_ptr 把释放时机绑定到作用域或引用计数,从根本上消除忘记释放、重复释放等问题。
立即学习“C++免费学习笔记(深入)”;
-
std::unique_ptr<int> p = std::make_unique<int>(42);—— 离开作用域自动delete -
std::shared_ptr<std::string> s = std::make_shared<std::string>("ok");—— 最后一个引用销毁时自动清理 - 注意:智能指针不能管理
new[],但std::unique_ptr<T[]>支持数组(如std::unique_ptr<int[]> arr(new int[10]);)
实际项目里最棘手的不是“怎么写 delete”,而是“谁该删”和“什么时候删”。裸指针一旦跨函数或跨线程传递,所有权就容易模糊;哪怕代码逻辑上正确,维护者也很难一眼看出某处 delete 是否多余或遗漏。


















