方姚子逸由于某些硬件平台不能任意访问地址数据只能在某些地址处取某些特定类型的数据并且处理器访问未对齐的内存时需要多次读取并对多余数据进行剔除相较于对齐内存访问耗费了更多的时间降低了数据访问效率因此需要内存对齐。
为结构体分配内存时分配的内存大小至少是各个字段的长度和。通常分配的结构体的长度会大于结构体各个字段的长度和因为结构体需要对齐即结构体各字段之间需要填充。
缺省情况下编译器为结构体的每个成员按其自然边界对齐方式分配空间并按照每个成员被声明的顺序在内存中顺序存储第一个成员的地址和整个结构体的地址相同。结构体整体的默认字节对齐值是结构体中所有成员中对齐参数最大值结构体长度的计算必须取所用过的所有对齐参数的整数倍。
结构体中每个成员的首地址是成员自身自然边界对齐值的整数倍如果成员自身大小大于指定对齐字节以指定对齐字节整数倍为基准对齐
结构体整体对齐方式取决于结构体中所有成员的自然边界对齐值最大值的整数倍如果最大成员大小超过指定对齐字节以指定对齐字节整数倍为基准对齐也叫补齐目的是多个结构体连续存储时也满足对齐要求。
内存字节对齐是GCC编译器对C语言进行的扩展。在缺省情况下C编译器为每一个变量或是数据单元按其自然边界对齐条件分配空间。
如果__attribute__((aligned(n)))作用于一个类型那么该类型的变量在分配地址空间时其存放的地址一定按照n字节对齐(n必须是2的幂次方)如果类型中的成员的自然边界对齐值大于n则按照机器字长32位或者64位对齐。类型占用的空间即大小需要是n的整数倍以保证在申请连续存储空间的时候每一个元素的地址也是按照n字节对齐。
最后是对整个结构体补齐该结构体中最大字节为8字节double类型大于指定对齐字节所以还是以4字节补齐为基准。整个结构体结束地址为38地址38不是4的整数倍需要额外加2个字节填充即整个结构体的大小为40字节。具体对齐结构如下图所示。
4字节对齐的地址是4100b字节的整数倍也就是说地址的二进制表示形式以00结尾因此可以通过以下方式对4字节对齐地址进行测试
|