gpt4 book ai didi

c++ - VTABLE 中的地址和直接地址获取之间的区别

转载 作者:行者123 更新时间:2023-11-30 03:46:39 25 4
gpt4 key购买 nike

#include <iostream>
#include <vector>
using namespace std;

class Foo
{
public:
virtual void f1()
{
cout << "Foo::f1()" << endl;
}
virtual void f2()
{
cout << "Foo::f2()" << endl;
}
virtual void f3()
{
cout << "Foo::f3()" << endl;
}
};
int main()
{
typedef void(*MethodFoo_f)();

Foo* ptr = new Foo();

cout << "Object address: " << ptr << endl;
cout << "__vfptr: " << (int*)*((int*)ptr) << endl;

for(int i = 0; i < 3; ++i)
{
int* e = (int*)*((int*)ptr) + i;
cout << "Address from __vfptr " << e;
auto t = &Foo::f1;
switch(i)
{
case 0: t = &Foo::f1; cout << ", address from main " << (void*&)t << " "; break;
case 1: t = &Foo::f2; cout << ", address from main " << (void*&)t << " "; break;
case 2: t = &Foo::f3; cout << ", address from main " << (void*&)t << " "; break;

}
cout << "execute: ";
auto func = (MethodFoo_f*)(e);
(*func)();
}

}

大家好,你能解释一下吗:为什么我们可以看到相同方法的地址不同。

Visual Studio 的示例输出

Object address: 007ADE28 __vfptr: 00E63B34

Address from __vfptr 00E63B34, address from main 00E51F23 execute: Foo::f1()

Address from __vfptr 00E63B38, address from main 00E51F1E execute: Foo::f2()

Address from __vfptr 00E63B3C, address from main 00E51F19 execute: Foo::f3()

如果 VTABLE 调用转换为

objPointer->(__vfptr + methodIndex)()

为什么在表中,我们保存地址的修改值?

最佳答案

我终于意识到你想要什么,你错过了一层间接。

ptr 指向对象
(假设 32 位和许多其他你不应该真正假设的东西):
*((int*)ptr) 是vtable的地址
(int*)*((int*)ptr)*((int**)ptr) 是同一地址的转换
(int*)*((int*)ptr)+i& (*((int**)ptr))[i] 是 vtable 中的一个位置你想要那个位置的内容:
*((int*)*((int*)ptr)+i)(*((int**)ptr))[i]

您在 func
中拥有额外的间接级别MethodFoo_f 是指向函数的指针类型,func 是指向 MethodFoo_f
的指针因此,对于每个函数,您期望相同的数字是指向函数指针的指针和指向函数的简单指针。

我仍然猜不到你从 auto t = &Foo::f1; 得到的指向函数的指针可靠地具有与实际的 void* 相同的内容函数的代码。但至少在正确的间接级别下,您可以将其与此进行比较。

关于c++ - VTABLE 中的地址和直接地址获取之间的区别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34004709/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com