C++ 中的悬空指针和删除命令

Danglings Pointers and Delete Command in C++

我注意到我的 C++ 代码中有一些非常奇怪的东西。

class A
{
    public:
    void doIt(){cout<<"hello"<<endl;}
};
int main() {
    A* a=new A();
    A* b=a;
    delete a;
    b->doIt();
    return 0;
}

我认为 delete 会从堆中擦除内存,而 b->doIt() 会失败。但是虽然 运行 这段代码有效,甚至可以打印 "hello".

为什么?

这很可能是因为 doIt 方法不使用 A class 的任何内部状态。因此,编译器可能将其优化为静态方法,并在静态 class 上下文中调用调用。指针悬空的事实并不能阻止该方法成为 运行.

但是,这是未定义的行为,更严格的编译器实际上可能会生成确实失败的代码。

I thought that delete will erase the memory from the heap

"erase" 记忆的唯一方法是用锤子。

内存被标记为"unused"并且对象在语义上被销毁。

and b->doIt() would fail

这是为什么?

没有任何机制可以为您做到这一点,在一般情况下也不会有

有责任不对不存在的对象调用函数。

实际上,它不会在这里崩溃,因为 doIt 中没有任何内容实际尝试访问对象的内存。请记住,函数并​​未存储 "in" 对象 — 它是您程序的一部分,并且您的程序仍然存在。

即使 doIt 访问 and/or 改变了对象的状态,只要该内存仍在活动页面中,您可能 仍然 不会崩溃。这正是 未定义行为 被定义为不可预测的原因。

避免。


  • 类似: Can a local variable's memory be accessed outside its scope?