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

use*_*735 12 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 ;
}
Run Code Online (Sandbox Code Playgroud)

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

2280712 2280716 2280720 16

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

2280712 2280720 2280721 13

Vov*_*ium 16

A 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
Run Code Online (Sandbox Code Playgroud)
  • a 偏移量为0,显然是8的倍数;
  • ch 在偏移4处,(也显然)是1的倍数;
  • s 偏移量为8,是4的倍数;
  • sizeof(struct data)等于[1](16)的偏移量,它需要是倍数的倍数max(8,1,4) = 8


Gre*_*ill 13

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
Run Code Online (Sandbox Code Playgroud)