int main()
{
myClass obj;
.... /* doing things */
....
delete &obj; /* illegal */
}
让我们假设myClass是一个适当的C ++类,其中包含所有内容。现在,我知道这是非法的,这个程序会在运行时崩溃。第一件事就是代码试图删除一个堆栈对象,然后在范围完成之后它再次被破坏。我想知道这种非法行动的内部情况。即删除会发生什么,它会调用析构函数吗?对你来说可能看起来很疯狂,但请帮助我理解。
答案 0 :(得分:6)
行为未定义。会发生什么将取决于类的详细信息,正在发生的事情,程序的内存管理器是如何实现的,您使用的编译器,您正在运行的系统,以及可能还有许多其他我没有的东西花时间思考。这非常类似于询问化学品储罐爆炸时会发生什么的细节。
答案 1 :(得分:2)
你缺少一件重要的事情 - 除了调用析构函数之外,delete
将释放用new
分配的内存,并将它返回到堆中。在堆栈分配变量上调用free是不安全的。要查看它是否会先调用析构函数,只需在cout
析构函数中添加一些myClass
- 在我的配置上调用析构函数,然后再进行分段错误。
#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;
}
来自MSDN:
当使用delete来释放C ++类对象的内存时,在释放对象的内存之前调用该对象的析构函数(如果该对象具有析构函数)。
答案 2 :(得分:1)
这是未定义的行为。标准,我们所有人生活和仰视的词语,说:
否则,提供给operator的值删除(void *) 标准库应该是前一个返回的值之一 调用operator new(size_t)或operator new(size_t, 标准库中的const std :: nothrow_t&amp;)
所以它是未定义的行为,任何事情都可能发生,并且它将取决于被错误删除的对象的实现,编译器,运气和其他事情。在内部询问“会发生什么”没有意义,因为任何事情都可能发生。最有可能的是,由于delete
运算符假定您正确使用它,最终会在堆栈中引入一些不可预测的更改,这会使任何事情变得混乱。也许你以前的帧指针被覆盖,也许一些荒谬的返回值被推送到一个函数,也许被保存的寄存器被覆盖,因此尝试恢复寄存器状态会导致非常非法的情况。无论发生什么,都很难看。
答案 3 :(得分:0)
经验法则:
对于每个
new
,应该只有一个delete
对于每个new[]
,应该只有一个delete[]
对于每个malloc
或calloc
,应该只有一个free
对于每个stack allocated
对象,不应该有任何明确的删除。
其他任何内容都会导致未定义的行为。
即。删除会发生什么,它会调用析构函数吗?
是的, delete 将首先调用对象析构函数。