简体   繁体   English

c++ 中的这个指针可能是 0xffffffff

[英]this pointer in c++ maybe 0xffffffff

After read Inside the C++ Object Model , I try to call member function from vptr.在阅读了 C++ Object Model 的内部后,我尝试从 v074pt15E683895D1AB4 调用成员 ZC1C425268E683895D1AB4

I found the following situation by accident我偶然发现了以下情况

gcc version 9.2.0 (tdm64-1) gcc 版本 9.2.0 (tdm64-1)

#include <iostream>

class Foo;
Foo* foo;

class FooBase
{
public:
    virtual void Bar1(){};
    virtual void Bar2(){};
};
class Foo : FooBase
{
public:
    void Bar1()
    {
        if (this == nullptr)
        {
            std::cout << "this == nullptr in Bar1" << std::endl;
        }
        else
        {
            std::cout << "this == " << this << " in Bar1" << std::endl;
            std::cout << "foo == " << foo << " in Bar1" << std::endl;
        }
        std::cout << "Bar1" << std::endl;
    }
};

int main()
{
    foo = new Foo;
    // std::cout << "foo == " << foo << " in main" << std::endl;

    int* vptr = reinterpret_cast<int*>(foo);
    int* bar1_ptr = reinterpret_cast<int*>(*vptr);

    typedef void (*Func1)();
    typedef void (*Func2)(Foo*);

    Func1 bar10 = (Func1)*bar1_ptr;
    Func2 bar11 = (Func2)*bar1_ptr;

    bar10(); // sometimes 'this == 0xffffffff in Bar1'
    bar11(nullptr); // this == nullptr in Bar1
    return 1;
}

When I comment std::cout << "foo == " << foo << " in main" << std::endl;当我评论std::cout << "foo == " << foo << " in main" << std::endl;

the output is output 是

this == 0x96ae0 in Bar1
foo == 0x96ae0 in Bar1
Bar1
this == nullptr in Bar1
Bar1

But when I uncomment std::cout << "foo == " << foo << " in main" << std::endl;但是当我取消注释std::cout << "foo == " << foo << " in main" << std::endl;

the output is output 是

foo == 0x1d6ae0 in main
this == 0xffffffff in Bar1
foo == 0x1d6ae0 in Bar1
Bar1
this == nullptr in Bar1
Bar1

Q1: Why this pointer has a default value foo == this ? Q1:为什么这个指针有一个默认值foo == this

Q2: Why this pointer was changed after uncomment? Q2:为什么取消注释后这个指针发生了变化?

When you access Bar1 via Func1, this ends up being whatever was on the stack in the first arg's position.当您通过 Func1 访问 Bar1 时,这最终会成为第一个 arg 的 position 中堆栈中的任何内容。 It wasnt a default value - it just happened to be there from your previous calls.这不是一个默认值——它只是碰巧在你之前的电话中出现。

No surprise that the stack can change with change to previous calls.堆栈会随着对先前调用的更改而更改,这并不奇怪。

As you probably found out, calling a class member functions can be implemented as a regular function that takes a class pointer as an argument.正如您可能发现的那样,调用 class 成员函数可以实现为将 class 指针作为参数的常规 function。 In your compiler and case, it looks as though the following are equivalent.在您的编译器和案例中,看起来以下内容是等价的。

foo->Bar1();
bar11(foo);

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

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