[英]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.