内存对齐__attribute __((aligned(8)))

我在书中得到了一个程序

#include  int main( ) { struct data { int a __attribute__( ( aligned ( 8 ) ) ) ; char ch __attribute__( ( aligned ( 1 ) ) ) ; float s __attribute__( ( aligned ( 4 ) ) ) ; } ; struct data e ; printf ( "\n%u %u %u", &e.a, &e.ch, &e.s ) ; printf ( "\n%d", sizeof ( e ) ) ; return 0 ; } 

当我在安装在Windows 7机器上的cygwin上运行它时。 我正在输出

2280712 2280716 2280720 16

为什么这个输出我得到了? 我期待着输出

2280712 2280720 2280721 13

sizeof始终是最大对齐的倍数,因为它实际上在给定类型的数组中以字符forms报告’step’,其中包括成员之间的填充,因此需要对齐它们之间的数组元素之间的填充。

struct data内存布局如下所示:

  00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 ... <--offset | | | struct data (element [0]) | (element [1]) | | | a |ch|::::::::| s |:::::::::::| a |ch|::::... | | |<----------- sizeof(struct data) ------------->| |::::| is padding 
  • a在偏移0处,显然是8的倍数;
  • ch在偏移4处,(也显然)是1的倍数;
  • s是偏移量8,是4的倍数;
  • sizeof(struct data)等于[1] (16)的偏移量,它必须是max(8,1,4) = 8倍数

aligned(N)属性通过在数据项之前插入填充字节,使当前数据项在N的倍数的地址上对齐。 你似乎期望它与包装有关,这是不同的。

您的结构似乎如下所示:

 Address Member ------- ------- 2280712 a [address aligned on multiple of 8] 2280713 a 2280714 a 2280715 a 2280716 ch [address aligned on multiple of 1] 2280717 (unused) 2280718 (unused) 2280719 (unused) 2280720 s [address aligned on multiple of 4] 2280721 s 2280722 s 2280723 s 

aligned(8)只表示&e.a的地址将与8对齐。它是(2280712)。 sizeof(int)大概是4,这就是为什么你的char最终在2280716(它的对齐要求为1,因此它没有理由被推到2280720)。 只需将sizeof(int)添加到调试输出中即可validation它。

如果要使用64位整数,则需要更改构建目标设置。