一、结构体描述
结构体对齐是C/C++优化结构体内存排布的一种机制,它的出现是为了解决跨总线寻址的问题。
例如对于以下结构:
struct stu {
char a;
int b;
};
如果不执行结构体对齐,它在内存中的排布应该是这样的:
对于字段b而言,它占四个字节,跨了两个总线地址,如果要取出b的值就要寻址两次。而如果把结构设计成以下形式:
对b的访问就只用寻址一次了,所以,为了减少cpu消耗,编译器会对结构进行优化,会对内存进行对齐。
二、对齐原则
结构体对齐遵循的原则:
- 第一个成员的首地址为0,每个成员的首地址是自身大小的整数倍,不够时填充空字节
- 结构体总大小是结构体中最大元素的整数倍,存在结构体嵌套时,最大元素是内部的结构体成员而不是这个结构体
2.1 规则一
struct Stu {
char name[7];
int age;
char sex;
short id;
int friends;
};
- name成员放在Stu成员的最开始,它占了7个字节,位于0-6
- age占四个字节,它本应该从第7个字节存放,但是7不能整除age的大小,它被放在第8个字节
- sex占一个字节,放在第12位
- id占两个字节,本应放在第13字节,但13无法整除2,此时会在id前面填充一个字节对齐
- 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后面填充了八个字节。
此处评论已关闭