首页
社区
课程
招聘
[原创]C++类的内存分布与std::typeInfor分析
发表于: 2024-9-5 15:46 8128

[原创]C++类的内存分布与std::typeInfor分析

2024-9-5 15:46
8128

1.如果类里面有虚函数,类前4个字节是个虚函数表的指针.(64位是前8字节)。

2.会和结构体一样,存在内存对齐行为(这里就不展开了)。

3.类的成员函数(非虚函数,虚函数会放在虚表里)不会占用类的内存。

1.例子中A和C中都有虚函数,B继承了A和C,B的内存中就有两个虚函数表;

2.内存布局和声明的顺序有对应关系,具体内存排列顺序请看 1的内容。

1自己的虚表还是首地址的地方,它和第一个虚表融合到了一起。(请看下面图片讲解)

1:B类的原型

img

2:C类的原型

img

3:C类内存结构,红色是他继承的 B A D 类,绿色是自己成员x内存。

img

4:查看下第一个也就是 0x000000014001C9A8地址。

img

你会发现原本B类里面只有三个虚函数此时内存中有4个虚函数,讲解:红色方框内是被C类重写的函数,绿色方框是B类自己两个虚函数(因为不重名所以没被重写),而最后一个蓝色方框是C类自己的boo虚函数。

5:其余两个类 A和D的虚表中只有三个函数(A和D函数同名只是打印内容不同)没有蓝色方块的函数,这里就不贴图了,我相信你们能理解。

6:以上5条都是以继承的形式进行讨论的。别的形式就不准确了。

C类:

1.第一个是自己,接下来依次声明排列。与继承内存布局不同。

此图是32位C++类的结构:

不过在64位下放的就不是指针而是一个偏移

我目前测试环境是vs2022下,别的编译器就不清楚了.

image-20240830224350914

1.取出虚表地址 0x000000014001c9a8。

image-20240830225703992

2.虚表地址减去void*大小(64位下8字节)也就是箭头指向地址。

image-20240830225858973

3.取出箭头地址转到,再加上12字节也就是方框中的数据(0x0001f3c8)。

4.0x140000000(模块基址)+0x0001f3c8。

image-20240830230149916

5.红色方框就是std::type_infor里面的数据

6.执行代码验证,学过汇编的同学都知道RAX一般情况下是用来存放函数返回值,本文中是(0x00000014001F3C8)。

image-20240830230728820

7.正向代码验证。

image-20240830230920681

image-20240830225355738

1.上图是有虚表的情况,调用了__RTtypeid函数其功能就是 本文中第四条所讲内容。

image-20240830225000821

2.没有虚表的情况,他将会直接std::type_infor对象地址指针赋值给目标。

1.x64下std::type_infor大小固定为24字节。

2.+0 偏移:存放着 type_infor 的虚函数表,里面有一个虚函数 为type_info::`scalar deleting destructor'(unsigned int)。

3.+8 偏移:_UndecoratedName = 0x0000000000000000 <NULL>,如图:


[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

收藏
免费 0
支持
分享
最新回复 (2)
雪    币: 25966
活跃值: (5042)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
图片不显示
2024-9-5 19:00
0
雪    币: 200
活跃值: (120)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
huangyalei 图片不显示

图片是放在github上的 ,我这边几台电脑都是能正常显示的。

最后于 2024-9-5 21:22 被学海无涯~编辑 ,原因: 打错字
2024-9-5 21:21
0
游客
登录 | 注册 方可回帖
返回
//