gpt4 book ai didi

c++ - 指向不同地址的虚表和函数指针

转载 作者:塔克拉玛干 更新时间:2023-11-03 01:20:21 25 4
gpt4 key购买 nike

我最近在 bitsquid 博客上阅读一篇关于如何管理内存的文章,作者开始谈论 vtable 以及编译器如何将指针添加到类中。这是 article 的链接.因此,因为我对 vtalbe 几乎一无所知,所以我开始在网上搜索解释。我遇到了this link .根据我阅读的内容,我编写了以下代码:

char cache[24];

printf("Size of int = %d\n", sizeof(int));
printf("Size of A = %d\n", sizeof(A));

A* a = new(cache)A(0,0);
printf("%s\n",cache);
printf("vTable : %d\n",*((int*)cache));
printf("cache addr: %d\n",&cache);

int* funcPointer = (int*)(*((int*)cache));
printf("A::sayHello: %d\n",&A::sayHello);
printf("funcPointer: %d\n",*funcPointer);

A 是一个具有两个整数成员和一个虚函数 sayHello() 的类。

编辑:这是类定义:

class A {
public:
int _x;
int _y;
public:
A(int x, int y) : _x(x), _y(y){ }
virtual void sayHello() { printf("Hello You!"); }
};

基本上我试图做的是查看 vtable 中的指针是否指向与我从 &A::sayHello 获得的地址相同的位置,但问题是当我运行程序,vtable中指针内的地址与sayHello()地址总是相差295。有谁知道为什么会这样?是否添加了某种我缺少的 header ?我在 64 位机器上运行 visual studio express 2008。

根据我的调试,*funcPointer 返回的地址是函数sayHello() 的真实地址。但为什么 &A::sayHello() 返回不同的地址?

最佳答案

C++ 有一个有趣的特性:

如果你拿一个指向虚函数的指针并使用它,虚函数将被解析并调用。

举个简单的例子

struct A
{
virtual DoSomething(){ printf("A"); }
};

struct B: public A
{
virtual DoSomething() { printf("B"); }
};

void main()
{
A * a, b;
void (A::*pointer_to_function)();

pointer_to_function = &A::DoSomething;
a = new A;
b = new B;

(a.*pointer_to_function)() //print "A"
(b.*pointer_to_function)() //print "B"
}

因此,您使用 &A::DoSomething 看到的地址是 trampoline 的地址,而不是真正的函数地址。

如果你去汇编,你会看到那个函数做了类似的事情(寄存器可能会改变但是代表 this 指针的 ecx):

mov eax, [ecx] ; Read vtable pointer
lea edx, [eax + 4 * function_index ] ; function_index being the index of function in the vtable
call edx

关于c++ - 指向不同地址的虚表和函数指针,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9983967/

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