对齐

  对齐指的是如何安排对象在内存中地址,要求某种类型对象的地址必须是某个值K(通常是2,4,8)的倍数,假设处理器总是从内存中取8个字节,则地址必须为8的倍数。

对齐的原则是任何K字节的基本对象的地址必须是K的倍数。

_Algnof 运算给出一个类型的对齐要求,

size_t d_align = _Alignof(float);

可以使用_Alignas说明符指定一个变量或类型的对齐值。但是,不应该要求该值小于基本对齐值。

_Alignof(double) char c1;
_Alignof(8) int i;

结构体对齐

结构体是多类型对象,确保每种数据类型都是按照指定方式来组织和分配,即每种类型都满足它的对齐规则。

考虑如下结构体。

struct s1
{
 int i;
 char c;
 int j;
};

假设编译器用最小9字节分配。如下

    0    4            5          9    

    [   i   ]   [    c    ][     j     ]

不满足字段i和字段j的4字节对齐要求。需要进行填充。如下

    0       4          5                    8         12    

    [   i   ]   [    c    ][  填充3字节   ][     j     ]

 结果,j的便宜了为8,整个结构体大小为12个字节。假设其实地址为(第一个i需要4倍数的地址)4x,c地址是4x+1,j地址就是 4x+8

结构体往后填充

考虑结构体

struct s1
{
 int i;
 char c;
 int j;
char k;
};

填充后如下。

           0   4          5                     8          12   13    

    [   i   ][    c    ][  填充3字节   ][     j     ][  k  ]

考虑结构体数组的内存分布,即struct s1 a[2];

           0    4          5                    8          12    13  17           

    [   i   ][    c    ][  填充3字节   ][     j     ][  k  ][   i   ][    c    ][  填充3字节   ][     j     ] [  k  ]

  在第二个i位置,它的地址为13+初始地址。初始地址一定为4x(能被4整除),13+4x不能被4整出,进行后填充。

       

      0  4          5                    8           12    13            16    20        21                 24        28         

   [   i   ][    c    ][  填充3字节   ][     j     ][  k  ][填充3字节][   i   ][    c    ][  填充3字节   ][     j     ][  k  ]

   

所以,为了浪费最小,结构体字段排序最好按照字节类型小的开始。比如上面的结构体

struct s1
{
char k;
 char c;
 int i;
 int j;
};

0     1     2          4     8     12

[  k  ][  c  ][  填充2字节  ][  i  ][  j  ]

也不需要后填充。

原文地址:https://www.cnblogs.com/shuiyonglewodezzzzz/p/10977582.html