例题1:
#pragma pack(4)
class TestB
{
public:
int aa; //第一个成员,放在[0,3]偏移的位置,
char a; //第二个成员,自身长为1,#pragma pack(4),取小值,也就是1,所以这个成员按一字节对齐,放在偏移[4]的位置。
short b; //第三个成员,自身长2,#pragma pack(4),取2,按2字节对齐,所以放在偏移[6,7]的位置。
char c; //第四个,自身长为1,放在[8]的位置。
};
这个类实际占据的内存空间是9字节
类之间的对齐,是按照类内部最大的成员的长度,和#pragma pack规定的值之中较小的一个对齐的。
所以这个例子中,类之间对齐的长度是min(sizeof(int),4),也就是4。
9按照4字节圆整的结果是12,所以sizeof(TestB)是12。
例题2:
#pragma pack(8)
struct S1{
char a; //第一个成员,按照min{1,8}=1对齐,放在[0]位置上
long b; //第二个成员,按照min{4,8}=4对齐,放在[4,7]位置上
};
struct S2 {
char c; //第一个成员,放在[0]偏移位置
struct S1 d; //第二个成员是个结构体,按照min{1,4}=4对齐,放到[4,11]位置上
long long e; //第三个成员min{8,8}=8,对齐,放到[16,23]位置上
};
#pragma pack()
sizeof(S2)结果为24.
1、结构体a中嵌套结构体b,则b作为一个整体的对齐方式按照结构体内部最大对齐字节数对齐
例题3:
#pragma pack(4)
struct S3{
long a; //第一个成员,放在[0,3]位置上
char *b; //第二个成员,放在[4,7]位置上
short c; //第三个成员,放在[8,9]
char d; //第四个成员,放到[10]
short e[5];//第五个成员,放到[12,21]
}
#pragma pack()
sizeof(S3)=24
1、数组对齐方式按照其单个元素的对齐方式,而不是数组整体大小
总结:
这里有三点很重要:
1.每个成员分别按自己的方式对齐,并能最小化长度
2.复杂类型(如结构)的默认对齐方式是它最长的成员的对齐方式,这样在成员是复杂类型时,可以最小化长度
3.对齐后的长度必须是成员中最大的对齐参数的整数倍,这样在处理数组时可以保证每一项都边界对齐