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

时间:2010-12-28 07:25:47

标签: c

我在一本书中得到了一个程序

#include <stdio.h>
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

3 个答案:

答案 0 :(得分:15)

sizeof始终是最大对齐的倍数,因为它实际上在给定类型的数组中以字符形式报告'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的倍数

答案 1 :(得分:12)

aligned(N)属性通过在数据之前插入填充字节,将{em>当前数据项与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

答案 2 :(得分:0)

对齐(8)只意味着&amp; e.a的地址将与8对齐。它是(2280712)。 sizeof(int)大概是4,这就是为什么你的char最终在2280716(它的对齐要求为1,所以没有理由把它推到2280720)。只需将sizeof(int)添加到调试输出中即可验证它。

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