对齐

1. 什么是对齐?

当你定义一个变量时,系统会给这个变量分配一段连续的空间。而由于CPU寻址的特殊性,32位 CPU 只能以 4 的整数倍来寻址。因此,如果一个变量被分配在两个不同的 4 字节块中,那么 CPU 就要读取两次,再将这个变量拼凑完成。为了 CPU 执行效率更高,需要进行字节对齐。

2. 对齐方式

对齐是为了 CPU 能够更高效率运行的,因此对齐的方式与CPU的类型密切相关。

2.1 64 位机器默认对齐

在64位操作系统上,如下数据结构占用的存储空间大小为多少字节:

struct A{
unsigned int a;
char b[2];
double c;
short d;
}

如果做一下简单的加法:4 + 2 + 8 + 2 = 16 显然是不对的。在 64 位机器上,复杂结构类型的对齐数为成员中占用空间最大的字节数,也就是 sizeof(double) = 8。因此 A 的结构为如下形式:

地址:| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 |
           {|------a---------|-----b----|不够c}{--------------------c---------------------------}{|----d------|----------------补充----------------------}
            |    第一次分配 8 个字节| 补充 |                    第二次分配8字节                                   第三次分配 8 字节

所谓 8 字节对齐便如上图所示。因此执行sizeof(A),将会得到 8 + 8 + 8 = 24
亦或者是

struct test
{
        char a[3];
        int b;
        char c;
};

为 4 字节对齐,执行sizeof(test),得到3 + (1) + 4 + 1 + (3) = 12

2.2 32 位机器默认对齐

32位机器上字节对齐与 64 位相类似,唯一不同之处在于 32 位机器对齐数只能 小于等于4(默认为4)。因此

struct test
{
    int a;
    float b;
    char c;
}

sizeof(test) = 12。4 + 4 + 1 +(3)

struct test2
{
    short a;
    float c;
}

sizeof(test2) = 8。2 + (2) + 4

2.2 程序中指定对齐方式

感谢稀稀拉拉的赞赏