C ++:可以反复安全地取消引用对象的未分配指针,这是为什么?

为什么此代码实际上可靠地起作用,不是不稳定的,未定义的? 它取消引用了对象的未分配悬空指针。 谢谢。

#include <iostream>
using namespace std;

class Base{
    public:
    void vf()
    {
        cout<<"vf\n";
    }
    void pr(){
        cout<<"vb\n";
    }
};

int main() {
    Base* b ;

    //Base * bp = new Base;   //trying to disrupt memory
    char ar[]= "ttttttttttt"; //trying to disrupt memory

    b->pr();
    char aa[]= "ttttttttttt";
    b->vf();
    return 0;
}
评论
  • 非主流网名
    非主流网名 回复

    欢迎来到未定义行为的奇妙世界!根据C ++规范,此问题的行为是不确定的,因此您看到的内容可能在您的系统上起作用,但在其他系统上崩溃,反之亦然。

    实际上,这里发生的事情可能是编译器如何为成员函数生成代码的产物。通常,成员函数如下所示:

    void doSomething() {
        cout << "Hello!" << endl;
    }
    

    可能会像是一个自由函数一样被编译:

    void Base_doSomething(Base* this) {
        cout << "Hello!" << endl;
    }
    

    从这个意义上说,当你写

    bf->doSomething();
    

    编译器将其视为已编写

    Base_doSomething(bf);
    

    and nothing bad happens, because Base_doSomething doesn't reference the this pointer, which is where all the bad things happen.

    Now, this is very brittle. If you try to read any of the data members of the Base type, this code will crash because then you are reading from a bad pointer. Similarly, if doSomething were a virtual function, you'd get a crash because calling a virtual function (typically) requires reading from the receiver object to find the vtable to determine which function to call, and a dangling pointer will then lead to a bad memory access.

    因此,总结一下:

    • This code leads to undefined behavior, so the particular behavior you're seeing isn't guaranteed to happen or work across platforms.
    • Although syntactically bp->doSomething() looks like a pointer dereference, it might not actually involve a pointer dereference.
    • Member functions are typically compiled as free functions that have an "implicit this" pointer passed as a first argument.
    • Virtual functions work differently than this, so you'd expect to see different behavior there.

    希望这可以帮助!