结构体及类对象的内存对齐
https://bbs.pediy.com/thread-222967.htm
环境:VS2015 (x86)
0x01 结构体的内存对齐
先看这个例子:
#include <Windows.h> #include <iostream> using namespace std; struct Monster { char Tamanonomae; int Shutendouji; char Tengu; }; int main() { Monster MonsterObject; MonsterObject.Tamanonomae = 'A'; MonsterObject.Shutendouji = 8888; MonsterObject.Tengu = 'B'; cout << sizeof(Monster) <<endl; return 0; }
输出的sizeof(Monster)的值为12,来看看结构体MonsterObject的内存:
结构体中的第一个和第三个成员虽然是char类型只占一个字节,但是后面的三个字节都被CC填充了,实际看起来是像int类型一样占了4个字节,所以一共占了12个字节。
换一下结构体中成员的位置:
struct Monster { char Tamanonomae; char Tengu; int Shutendouji; };
输出的sizeof(Monster)的值不再是12了,而是8~,再来看看结构体MonsterObject的内存:
可以发现第一第二个char成员紧紧相邻在一起占了两个字节,但是其后依然填充了两个字节的CC,加上int类型的4字节。所以一共8个字节。
现在,根据实践以及书本博客提及的内存对齐规则,总结了条结构体的内存对齐规则:
1.结构体的每个成员相对于结构体首地址的偏移量都是成员大小的整数倍。
2.结构体的总大小为最结构体最宽基本类型成员的整数倍。
3.结构体的首地址能够被最宽基本类型成员所整除。
0x02 类对象的内存对齐
将上文代码中的struct关键字改为class,再在类中添加public属性:‘
#include <Windows.h> #include <iostream> using namespace std; class Monster { public: char Tamanonomae; char Tengu; int Shutendouji; }; int main() { Monster MonsterObject; MonsterObject.Tamanonomae = 'A'; MonsterObject.Shutendouji = 8888; MonsterObject.Tengu = 'B'; cout << sizeof(Monster) <<endl; return 0; }
输出的sizeof(Monster)的值依然是是8,与结构体无异常。
向结构体中添加一个静态成员和一个成员函数:
class Monster { public: char Tamanonomae; char Tengu; int Shutendouji; static int v1; void Function() { printf("SHChronic\n"); } };
输出的结果依然是8没有改变,由此可以验证结构体与类对象的区别只是默认访问属性的不同,并且静态数据成员与成员函数不会算入类对象的大小中。对于一个没有父类的的类对象,他的内存模型与结构体相同,也就是内存对齐方式是一样的。