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

Danglings Pointers and Delete Command in C++

本文关键字:命令 C++ 删除 空指针      更新时间:2023-10-16

我注意到我的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"。

为什么?

我以为删除会从堆中删除内存

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

内存被标记为"未使用",对象在语义上被销毁。

b->doIt()会失败

这是为什么呢?

没有适当的机制可以为您执行此操作,在一般情况下也不可能有机制。

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

实际上,

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

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

避免。


  • 类似:可以在其范围之外访问局部变量的内存吗?

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

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