获取C++虚表地址和虚函数地址
来源:互联网 发布:淘宝gsx查询 编辑:程序博客网 时间:2024/05/18 02:15
获取C++虚表地址和虚函数地址
By qianghaohao
学过C++的应该都对虚表有所耳闻,在此就不过多介绍概念了,通过实
例来演示一下如何获取虚表地址和虚函数地址。
简单说一下虚表的概念:在一个类中如果有虚函数,那么此类的实例中就有
一个虚表指针指向虚表,这个虚表是一块儿专门存放类的虚函数地址的内存。
图示说明本文的主题(先看图更容易后面代码中的指针操作):
代码如下(要讲解的都在代码的注释中说明了):
class Base {public: virtual void f() { cout << "Base::f" << endl; } virtual void g() { cout << "Base::g" << endl; } void h() { cout << "Base::h" << endl; }};typedef void(*Fun)(void); //函数指针int main(){ Base b; // 这里指针操作比较混乱,在此稍微解析下: // *****printf("虚表地址:%p\n", *(int *)&b); 解析*****: // 1.&b代表对象b的起始地址 // 2.(int *)&b 强转成int *类型,为了后面取b对象的前四个字节,前四个字节是虚表指针 // 3.*(int *)&b 取前四个字节,即vptr虚表地址 // // *****printf("第一个虚函数地址:%p\n", *(int *)*(int *)&b);*****: // 根据上面的解析我们知道*(int *)&b是vptr,即虚表指针.并且虚表是存放虚函数指针的 // 所以虚表中每个元素(虚函数指针)在32位编译器下是4个字节,因此(int *)*(int *)&b // 这样强转后为了后面的取四个字节.所以*(int *)*(int *)&b就是虚表的第一个元素. // 即f()的地址. // 那么接下来的取第二个虚函数地址也就依次类推. 始终记着vptr指向的是一块内存, // 这块内存存放着虚函数地址,这块内存就是我们所说的虚表. // printf("虚表地址:%p\n", *(int *)&b); printf("第一个虚函数地址:%p\n", *(int *)*(int *)&b); printf("第二个虚函数地址:%p\n", *((int *)*(int *)(&b) + 1)); Fun pfun = (Fun)*((int *)*(int *)(&b)); //vitural f(); printf("f():%p\n", pfun); pfun(); pfun = (Fun)(*((int *)*(int *)(&b) + 1)); //vitural g(); printf("g():%p\n", pfun); pfun();}
参考文献:
http://blog.csdn.net/haoel/article/details/1948051 (注:此文的取虚表地址代码有问题)
0 0
- 获取C++虚表地址和虚函数地址
- 获取C++虚表地址和虚函数地址
- 虚函数表获取的函数地址和函数实际地址一样吗?
- C函数获取IP地址
- 虚函数地址表
- C++中访问虚函数表获取虚函数地址
- 获取C++类成员虚函数地址
- linux c函数获取系统IP地址
- linux c函数获取系统IP地址
- gdb查看内存地址和栈中的值—查看虚函数表、函数地址
- 虚函数表存放地址
- 获取system和LoadLibraryA函数的地址
- 如何通过函数名获取虚函数的地址?
- [C#]获取IP地址以及获取地址
- 获取ip地址函数
- 获取ip地址函数
- 获取IP地址函数
- android 获取函数地址
- Struts2标签库
- Java excel表 导出 POI2003
- git submodule 管理子工程
- socket中的函数遇见EINTR的处理
- 属性动画
- 获取C++虚表地址和虚函数地址
- PHP学习之路——类与面向对象
- Fragment全解析系列(一):那些年踩过的坑
- 用自己的数据训练Faster-RCNN
- 理解 Java GC(三)
- 交换知识
- Spring之IoC----常见类型数据的注入
- shell(一)
- flume源码分析--Log4j日志直接发送到Flume过程分析(三)