一、结构体描述

结构体对齐是C/C++优化结构体内存排布的一种机制,它的出现是为了解决跨总线寻址的问题。

例如对于以下结构:

struct stu {
    char a;
    int b;
};

如果不执行结构体对齐,它在内存中的排布应该是这样的:

对于字段b而言,它占四个字节,跨了两个总线地址,如果要取出b的值就要寻址两次。而如果把结构设计成以下形式:

对b的访问就只用寻址一次了,所以,为了减少cpu消耗,编译器会对结构进行优化,会对内存进行对齐。

二、对齐原则

结构体对齐遵循的原则:

  1. 第一个成员的首地址为0,每个成员的首地址是自身大小的整数倍,不够时填充空字节
  2. 结构体总大小是结构体中最大元素的整数倍,存在结构体嵌套时,最大元素是内部的结构体成员而不是这个结构体

2.1 规则一

struct Stu {
    char name[7];
    int age;
    char sex;
    short id;
    int friends;
};
  1. name成员放在Stu成员的最开始,它占了7个字节,位于0-6
  2. age占四个字节,它本应该从第7个字节存放,但是7不能整除age的大小,它被放在第8个字节
  3. sex占一个字节,放在第12位
  4. id占两个字节,本应放在第13字节,但13无法整除2,此时会在id前面填充一个字节对齐
  5. friends放在第16个字节开始

使用vs查看内存分布可以看到,name和sex后面被填充了一个字节:

1>class Stu    size(20):
1>    +---
1> 0    | name
1>      | <alignment member> (size=1)
1> 8    | age
1>12    | sex
1>      | <alignment member> (size=1)
1>14    | id
1>16    | friends
1>    +---

2.2 规则二

struct Nginx {
    struct Stu stu;
    char c;
};

当结构体中包含结构体时,此时最大的元素是name,它对齐后占8个字节,为了维持对齐的特性,会在Nginx成员后面继续填充:

1>class Nginx    size(24):
1>    +---
1> 0    | Stu stu
1>20    | c
1>      | <alignment member> (size=3)
1>    +---

可以看到c后面填充了八个字节。

最后修改:2019 年 04 月 28 日
喜欢就给我点赞吧