析构函数中直接 delete[] 会崩溃,因未初始化或已释放的指针导致未定义行为;应初始化为 nullptr 并判空释放,或改用 unique_ptr 自动管理;person** 需先逐个 delete 元素再 delete[] 数组。

析构函数里直接 delete[] 会崩溃?检查指针是否为 nullptr
成员指针若未初始化或已被释放过,delete[] 会触发未定义行为——常见表现是程序在析构时 SIGSEGV 或 abort。C++ 不保证未初始化指针为 nullptr,野指针 + delete[] = 高概率崩溃。
安全做法是在构造函数中显式初始化所有指针成员为 nullptr,并在析构函数开头加判空:
class DataHolder {
int* buffer_;
public:
DataHolder() : buffer_(nullptr) {}
~DataHolder() {
if (buffer_) { // 必须判空
delete[] buffer_;
buffer_ = nullptr; // 二次释放防护
}
}
};
数组指针用 unique_ptr 替代 raw 指针更省心
手动管理 new int[N] + delete[] 容易漏、容易错,尤其在异常路径或多次赋值后。用 std::unique_ptr<int></int> 能让编译器自动调用数组版析构,无需写 delete[],也天然规避悬挂和重复释放。
-
std::unique_ptr<int></int>是特化模板,构造时传new int[N],析构时自动用delete[] - 不能用
std::unique_ptr<int></int>管理数组,否则只调delete,造成未定义行为 - 访问仍用
ptr[i],语义一致,无性能开销
class SafeArray {
std::unique_ptr<int> data_;
size_t size_;
public:
SafeArray(size_t n) : size_(n), data_(new int[n]) {}
// 析构函数完全不用写 —— unique_ptr 自动处理
};</int>
结构体指针数组(Person**)的析构必须分两层释放
如果成员是 Person** persons_(即“指针的数组”,每个元素指向一个堆上 Person 对象),析构时不能只 delete[] persons_,否则只释放了指针数组本身,所有 Person 对象都泄漏了。
正确顺序是:
- 遍历
persons_[i],对每个非空Person*调用delete(注意:单个对象用delete,不是delete[]) - 再
delete[] persons_释放指针数组本身 - 每步都要判空,且释放后置
nullptr(尤其多人协作时防误用)
~PersonManager() {
if (persons_) {
for (size_t i = 0; i <h3>析构中抛异常是危险信号,禁止在 ~T() 里 throw</h3><p>C++ 标准规定:若析构函数在栈展开(stack unwinding)过程中抛出异常,程序直接调用 <code>std::terminate()</code> 终止。而释放内存失败(如自定义删除器出错)可能引发异常,所以所有资源释放逻辑必须是 <code>noexcept</code> 的。</p><p>这意味着:</p>
- 避免在析构函数里做可能抛异常的操作(如文件 I/O、网络调用)
- 用
std::unique_ptr/std::shared_ptr时,确保其删除器不抛异常(默认delete和delete[]是noexcept) - 若必须用自定义删除器,务必用
noexcept声明并吞掉内部异常
最稳妥的做法,就是别在析构函数里留任何可能失控的代码分支——释放内存这事,越简单越安全。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











