獲取C++虛函數表地址和虛函數地址
阿新 • • 發佈:2018-04-30
rtu 虛函數地址 cpp 32位 對象 知識點 cout virt def
1.先介紹C++類的內存結構,大家可以看以下博客,覺得不錯
https://blog.csdn.net/fenxinzi557/article/details/51995911
其中和本次相關的知識點是一個有虛函數的類的前4個字節是指向虛函數表首地址的指針_vfptr
2.下面開始說具體的求解過程
class AA { public: virtual void func1() { cout << "AA ::func1" << endl; } virtual void func2() { cout << "AA ::func2" << endl; } void func3() { cout << "AA::func3" << endl; } }; typedef void(*Fun)(void); //函數指針 int main() { AA a; // *****printf("虛表地址:%p\n", *(int *)&a); 解析*****: // 1.&a代表對象a的起始地址 // 2.(int *)&a 強轉成int *類型,為了後面取a對象的前四個字節,前四個字節是虛表指針 // 3.*(int *)&a 取前四個字節,即vptr虛表地址 // *****printf("第一個虛函數地址:%p\n", *(int *)*(int *)&a);*****: // 根據上面的解析我們知道*(int *)&a是vfptr,即虛表指針.並且虛表是存放虛函數指針的 // 所以虛表中每個元素(虛函數指針)在32位編譯器下是4個字節,因此(int *)*(int *)&a // 這樣強轉後為了後面的取四個字節.所以*(int *)*(int *)&a就是虛表的第一個元素. // 即f()的地址. // 那麽接下來的取第二個虛函數地址也就依次類推. 始終記著vfptr指向的是一塊內存, // 這塊內存存放著虛函數地址,這塊內存就是我們所說的虛表. // printf("虛表地址:%p\n", *(int *)&a); printf("第一個虛函數地址:%p\n", *(int *)*(int *)&a); printf("第二個虛函數地址:%p\n", *((int *)*(int *)(&a) + 1)); Fun pfun = (Fun)*((int *)*(int *)(&a)); //virtual func1(); printf("func1():%p\n", pfun); pfun(); pfun = (Fun)(*((int *)*(int *)(&a) + 1)); //virtual func2(); printf("func2():%p\n", pfun); pfun(); }
獲取C++虛函數表地址和虛函數地址