问题:
A)
sizeof(TestStruct5) = ?
B)
TestStruct5 的c 后面空了几个字节接着是d?
TestStruct4 中,成员a 是1 字节默认按1 字节对齐,指定对齐参数为8,这两个值中取1,a
按1 字节对齐;成员b 是4 个字节,默认是按4 字节对齐,这时就按4 字节对齐,所以sizeof(TestStruct4)应该为8;TestStruct5 中,c 和TestStruct4 中的a 一样,按1 字节对齐,而d 是个结构,它是8 个字节,它
按什么对齐呢?对于结构来说,它的默认对齐方式就是它的所有成员使用的对齐参数中最大的一个, TestStruct4 的就是4.所以,成员d 就是按4 字节对齐.成员e 是8 个字节,它是默认按8字节对齐,和指定的一样,所以它对到8 字节的边界上,这时,已经使用了12 个字节了,所以又添加了4 个字节的空,从第16 个字节开始放置成员e.这时,长度为24,已经可以被8(成员e 按8字节对齐)整除.这样,一共使用了24 个字节.内存布局如下(*表示空闲内存,1 表示使用内存。单位为1byete):
a b
TestStruct4 的内存布局:1***,1111,
c
TestStruct4.a TestStruct4.b d
TestStruct5 的内存布局: 1***, 1***, 1111, ****,11111111
这里有三点很重要:
首先,每个成员分别按自己的方式对齐,并能最小化长度。
其次,复杂类型(如结构)的默认对齐方式是它最长的成员的对齐方式,这样在成员是复杂类型时,可以最小化长度。
然后,对齐后的长度必须是成员中最大的对齐参数的整数倍,这样在处理数组时可以保证每一项都边界对齐。
补充一下,对于数组,比如:char a[3];它的对齐方式和分别写3 个char 是一样的.也就是说它还是按1 个字节对齐.如果写: typedef char Array3[3];Array3 这种类型的对齐方式还是按1个字节对齐,而不是按它的长度。
但是不论类型是什么,对齐的边界一定是1,2,4,8,16,32,64....中的一个。
另外,注意别的#pragma pack 的其他用法:
#pragma pack(push) //保存当前对其方式到packing stack
#pragma pack(push,n) 等效于
#pragma pack(push)
#pragma pack(n) //n=1,2,4,8,16 保存当前对齐方式,设置按n 字节对齐
#pragma pack(pop) //packing stack 出栈,并将对其方式设置为出栈的对齐方 |