我很难理解为什么我在调用delete时会调用null指针的析构函数。由于指针的内容为null,并且甚至没有为mallocnew的对象保留任何空间它叫什么解构函数?

class Sak{
    public:
        Sak(){cout << "defalt constructor" << endl;}
        ~Sak(){
            cout << "deconstructor" << endl;
        }
};

int main(int argc, char *argv[])
{
    Sak* s;
    delete s;

    system("PAUSE");
    return EXIT_SUCCESS;
}


输出:

deconstructor
Press any key to continue . . .

最佳答案

您的Sak* s是一个未初始化的变量-它可能根本包含任何垃圾值。从未初始化的值读取是未定义的行为,因此一旦尝试执行该操作,程序就会被破坏。

尽管如此,实际上-为了解释观察到的行为-大多数实现都会读取s的堆栈地址处的所有内容,并将其传递给delete。如果该值恰好为0,则delete将不执行任何操作-根据标准。否则-我们的情况类似于:

Sak* s = (Sak*)1;
delete s;


delete通常对非0指针执行的操作是调用析构函数-~Sak-然后尝试释放内存(这也将是未定义的行为,并且可能会使程序崩溃或不会崩溃)。不过,您首先看到析构函数的输出并不奇怪。

还值得注意的是,析构函数调用通常将对象地址(例如,上面代码的1)传递为this指针:您的析构函数不会以任何方式使用this,甚至不会隐式使用(例如,为具有非平凡析构函数的数据成员(例如std::string)调用析构函数,因此您的析构函数很可能会成功返回。

关于c++ - 为什么在空指针上调用析构函数,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/24482643/

10-11 15:15