简体   繁体   English

C++:指向 object 的未分配指针可以反复安全地取消引用……为什么?

[英]C++ : unallocated pointer to object can be repeatedly safely dereferenced… why?

why is this code practically reliably working, is not unstable, undefined?为什么这段代码实际上可靠地工作,不是不稳定的,未定义的? it's dereferencing unallocated, dangling pointers to objects.它取消引用未分配的、悬空的指向对象的指针。 thanks.谢谢。

#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;
}

Welcome to the Wonderful World of Undefined Behavior , According to the C++ spec, the behavior of this problem is undefined, so what you're seeing might work on your system but crash on others.欢迎来到未定义行为的奇妙世界,根据 C++ 规范,此问题的行为是未定义的,因此您所看到的可能在您的系统上工作但在其他系统上崩溃。 or vice-versa.或相反亦然。

Practically speaking, what's happening here is probably an artifact of how the compiler generates code for member functions.实际上,这里发生的事情可能是编译器如何为成员函数生成代码的产物。 Typically, a member function that looks like this:通常,成员 function 如下所示:

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

would probably be compiled as if it were a free function like this:可能会被编译为像这样的免费 function :

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

In that sense, when you write从这个意义上说,当你写

bf->doSomething();

the compiler treats it as if you've written编译器将其视为您已编写

Base_doSomething(bf);

and nothing bad happens, because Base_doSomething doesn't reference the this pointer, which is where all the bad things happen.并没有发生任何不好的事情,因为Base_doSomething没有引用this指针,这是所有坏事发生的地方。

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.如果您尝试读取Base类型的任何数据成员,则此代码将崩溃,因为您正在从错误的指针中读取。 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. 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 访问。

So, to summarize:所以,总结一下:

  • 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.尽管在语法上bp->doSomething()看起来像指针解引用,但它实际上可能不涉及指针解引用。
  • Member functions are typically compiled as free functions that have an "implicit this " pointer passed as a first argument.成员函数通常编译为具有“隐式this ”指针作为第一个参数传递的自由函数。
  • Virtual functions work differently than this, so you'd expect to see different behavior there.虚函数的工作方式与此不同,因此您希望在那里看到不同的行为。

Hope this helps!希望这可以帮助!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM