首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么解构函数会调用空指针?

为什么解构函数会调用空指针?
EN

Stack Overflow用户
提问于 2014-06-30 03:39:21
回答 2查看 146关注 0票数 0

我很难理解为什么当我调用delete.Since时调用空指针的反编译器,指针的内容是null,我甚至没有为对象保留任何空间( mallocnew ),它调用的是什么解构函数?

代码语言:javascript
复制
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;
}

产出:

代码语言:javascript
复制
deconstructor
Press any key to continue . . .
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-06-30 03:51:52

您的Sak* s是一个未初始化的变量--它可能包含任何垃圾值。从未初始化的值读取是未定义的行为,因此程序一旦尝试就会中断。

然而,在实践中--为了解释观察到的行为--大多数实现都会读取位于s堆栈地址的任何内容,并将其传递给delete。如果该值恰好为0,那么delete将什么也不做--按照标准。否则--我们遇到类似的情况:

代码语言:javascript
复制
Sak* s = (Sak*)1;
delete s;

delete通常对非0指针所做的事情是调用析构函数- ~Sak -然后尝试释放内存(这也是未定义的行为,并且可能会或不会使程序崩溃)。不过,看到析构函数首先输出并不令人惊讶。

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

票数 4
EN

Stack Overflow用户

发布于 2014-06-30 03:46:07

因为引用的内容为空

有两个错误。

  1. 没有任何参考资料。你有一个指针。C++指针和C++引用都是句柄的类型。C#和Java中的引用以及C#中的指针也是如此。但是这些句柄类型之间没有100%的重叠,它们是否支持地址算法(只有C++和C#指针),以及它们是否可以重新分配(除了C++引用之外)。
  2. 此指针的内容不是null。它未初始化。

您的代码在一个野生指针上调用delete。那是未定义的行为。使用野生this指针调用析构函数只是未定义行为可能导致的一个例子。

它在叫什么破坏者?

C++根据用于调用它们的变量、引用或指针的类型查找非虚拟成员函数。在您的例子中,析构函数不是虚拟的。因此,编译器将delete s;转换为逻辑以测试指针值是否为null,然后使用该指针值作为this指针调用Sak::~Sak析构函数,这就不足为奇了。但是这种行为是没有定义的,其他事情也可能发生,包括进程中其他内存的随机损坏以及更糟的(可能是打开的文件的损坏,也影响了程序的未来运行)。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/24482643

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档