码迷,mamicode.com
首页 > 编程语言 > 详细

获取C++虚函数表地址和虚函数地址

时间:2018-04-30 17:55:25      阅读:167      评论:0      收藏:0      [点我收藏+]

标签:32位   fun   开始   func   \n   知识点   指针   一个   函数地址   

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++虚函数表地址和虚函数地址

标签:32位   fun   开始   func   \n   知识点   指针   一个   函数地址   

原文地址:https://www.cnblogs.com/YachenLee/p/8973832.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!