字节对齐原因:
1)平台原因(移植原因):不是所有的硬件平台都能访问任意地址上的任意数据,某些硬件平台只能在某些地址处取某些特定类型的数据,否则抛出硬件异常
2)硬件原因:经过内存对齐之后,CPU的内存访问速度大大提升,帮助cpu寻址。
【注意】(对齐位数跟处理器位数和编译器都有关)VS, VC等编译器默认是#pragma pack(8),所以测试我们的规则会正常;注意gcc默认是#pragma pack(4),并且gcc只支持1,2,4对齐。
改变缺省的对界条件(指定对界):
- 使用伪指令#pragma pack (n),C编译器将按照n个字节对齐。
- 使用伪指令#pragma pack(),取消自定义字节对齐方式。
对齐规则
规则一:结构体的每个成员相对于结构体的首地址的偏移量,都是基本成员大小的整数倍。比如
struct{ int a; //4 首地址&a char b; //1 第二个成员&b相对于第一个成员&a是整数倍 double c; //8 }
规则二: 如果有嵌套结构体或者有联合类型,那么内嵌结构体的第一个成员变量在外结构体中的偏移量,是内嵌结构体或联合体中那个数据类型大小最大的成员变量的倍数。
规则三: 整个结构体的大小要是这个结构体内数据类型大小最大的成员变量的倍数。如果有内嵌结构体,那么取内嵌结构体中数据类型大小最大的成员变量作为计算外结构体整体大小的依据。
最终有效的字节对齐值:
在自身字节对齐值和编译器要求的字节对齐值中取较小的。
比如:Linux 64位默认对齐为8位,下面输出为16,long在64位下为8位
typedef struct Test {