C++内存对齐
请记住三条内存规则(在没有#pragam pack宏的情况下):
1.数据成员对齐规则:struct, union的数据成员,第一个数据成员放在offset为0的地方,之后的数据成员的存储起始位置都是放在该数据成员大小的整数倍位置。如在32bit的机器上,int的大小为4,因此int存储的位置都是4的整数倍的位置开始存储。
2.结构体作为数据成员的对齐规则:在一个struct中包含另一个struct,内部struct应该以它的最大数据成员大小的整数倍开始存储。如 struct A 中包含 struct B, struct B 中包含数据成员 char, int, double,则 struct B 应该以sizeof(double)=8的整数倍为起始地址。
3.收尾工作的对齐规则:整个struct的大小,应该为最大数据成员大小的整数倍。
实例演示:
struct A
{
char a; //内存位置: [0]
double b; // 内存位置: [8]...[15]
int c; // 内存位置: [16]...[19] ---- 规则1
}; // 内存大小:sizeof(A) = (1+7) + 8 + (4+4) = 24, 补齐[20]...[23] ---- 规则3
struct B
{
int a, // 内存位置: [0]...[3]
A b, // 内存位置: [8]...[31] ---- 规则2
char c, // 内存位置: [32]
}; // 内存大小:sizeof(B) = (4+4) + 24 + (1+7) = 40, 补齐[33]...[39]
*注释:(1+7)表示该数据成员大小为1,补齐7位;(4+4)同理。
如果把这个例子看懂了,那内存对齐就没有问题了!:)
有#pragam pack宏的情况下:
如果在代码前添加 #pragam pack(1),则 sizeof(A) = 1 + 8 + 4 = 13; sizeof(B) = 4 + 13 + 1 = 18; 看懂#pragam pack(1)的作用了吗?告诉编译器按照1来进行内存对齐,即没有内存对齐!
#pragam pack(2),sizeof(A) = ?, sizeof(B) = ? 赶紧实践下把!