非法删除堆栈对象 让假设MyC类是一个适当的C++类,所有的东西都放在适当的位置。现在,我知道这是非法的,这个程序将在运行时崩溃。首先,代码试图删除堆栈对象,然后在作用域完成后,它将再次被删除。我想知道这次非法行动的内部情况。i、 删除会发生什么,它会调用析构函数吗?您可能觉得这很疯狂,但请帮助我理解。

非法删除堆栈对象 让假设MyC类是一个适当的C++类,所有的东西都放在适当的位置。现在,我知道这是非法的,这个程序将在运行时崩溃。首先,代码试图删除堆栈对象,然后在作用域完成后,它将再次被删除。我想知道这次非法行动的内部情况。i、 删除会发生什么,它会调用析构函数吗?您可能觉得这很疯狂,但请帮助我理解。,c++,C++,您缺少一件重要的事情-除了调用析构函数之外,delete将释放分配给new的内存,并将其返回堆。对堆栈分配的变量调用free是不安全的。若要查看它是否会首先调用析构函数,只需将一些cout放在myClass析构函数中-在我的配置中,它在分段错误之前调用析构函数 int main() { myClass obj; .... /* doing things */ .... delete &obj; /* illegal */ } #包括 使用名称空

您缺少一件重要的事情-除了调用析构函数之外,
delete
将释放分配给
new
的内存,并将其返回堆。对堆栈分配的变量调用free是不安全的。若要查看它是否会首先调用析构函数,只需将一些
cout
放在
myClass
析构函数中-在我的配置中,它在分段错误之前调用析构函数

int main()
{
    myClass obj;

    ....    /* doing things */
    ....

    delete &obj; /* illegal */
}
#包括
使用名称空间std;
类myClass
{
公众:
~myClass(){cout经验法则:

对于每个
应该只有一个
delete

对于每个
new[]
,应该只有一个
delete[]

对于每个
malloc
calloc
都应该有一个
free

对于分配的每个
堆栈
对象,不应进行任何显式删除。

任何其他行为都会导致未定义的行为


i、 删除会发生什么,它会调用析构函数吗


是的,delete将首先调用objects destructor。

行为未定义。发生的情况将取决于类的详细信息、其他情况、程序内存管理器的实现方式、使用的编译器、运行的系统,以及我没有花时间考虑的许多其他问题。这很像是询问化学品储罐爆炸时发生的详细情况。

这是未定义的行为。标准,即我们赖以生存和尊敬的词语,说:

否则,在中提供给运算符delete(void*)的值 标准库应为前一个数据库返回的值之一 调用运算符new(size_t)或运算符new(size_t), 标准库中的const std::nothrow\u t&)


这是一种未定义的行为,任何事情都可能发生,这取决于被错误删除的对象的实现、编译器、运气和其他因素内部没有意义,因为任何事情都可能发生。最有可能的是,由于
delete
操作符假定您正确使用了它,您最终在堆栈中引入了一些不可预测的更改,这可能会把任何事情搞砸。可能您以前的帧指针被覆盖,可能一些可笑的返回值被推到了一个有趣的位置操作时,可能已保存的寄存器被覆盖,因此尝试还原寄存器状态会导致非常非法的情况。无论发生什么情况,这都很糟糕。

它可能会崩溃,但与未定义的行为一样,另一方面,它可能不会崩溃,或者在大多数情况下崩溃,但并不总是如此,甚至会导致崩溃。更重要的是问题是,真的没有办法知道这将如何处理,未定义行为的性质在大多数情况下是不可预测的。通过检查非优化构建中生成的代码不难发现它实际上做了什么。这不是一个重复。OP这里不是问它是否安全,他们知道它不是。@jrok该线程的答案仍然是100%适用于这个问题:这是未定义的行为。
#include <iostream>

using namespace std;

class myClass
{
 public:
     ~myClass(){ cout << "Destructor" << endl; }

};


int main()
{
        myClass A;
        delete &A;
        cout << "End of main\n";
        return 0;
}