看如下结构体:
#include <stdio.h>
typedef struct _STU
{
int id;
char name[20];
char sex;
int age;
float score;
char addr[30];
}STU;
int main()
{
STU s;
printf("%d\n", sizeof(s));
return 0;
}
#include <stdio.h>
typedef struct _STU
{
int id;
char name[20];
char sex;
char addr[30];
int age;
float score;
}STU;
int main()
{
STU s;
printf("%d\n", sizeof(s));
return 0;
}
这两个结构体的成员是一摸一样的,只是位置发生了变化,为什么他们俩所占的内存空间就不一样呢,而且按平常算结构体变量空间的方法来算,这个结构体应该是(4+20+1+4+4+30)=63个字节,但是并没有一个答案是63.
这就是因为内存对齐:
如图所示:
(1)这是一个结构体变量在开辟存储空间,结构体变量的第一个成员变量是int型,他的偏移量为min(8,int)=4;而存储起始位置为0,可以整除4,所以int从0-4占了四个字节;
(2)到了第二个成员变量,他的类型是char,而min(8,1)=1;他从4开始,而4可以整除1,所以也不用对齐,而他是一个有20个字节长度的数组;
(3)所以第三个成员变量从24开始,而他也是char型min(8,1)=1,24可以整除1;所以不用对齐,到了25;
(4)下一个成员是int型的,而min(8,int)=4,25不能整除4,所以现在就需要内存对齐,开始补到28,28可以整除4,所以从25–28的内存是空的,这个数据存储位置从28开始;
(5)下一个成员是int,min(8,int)=4,28可以整除4,不用对齐;
(6)下一个成员是float,min(8,int)=4,32可以整除4,也不用对齐;
现在到了36,下一个成员类型为charmin(8,1)=1,36可以整除1,不用对齐,最终使用了66个字节的存储空间,
(7)但是最终整个结构体还要进行一次内存对齐,结构体对齐是系统默认字节数与自己成员中占最大字节的数进行比较,min(8,4)=4;所以总体应该是4的倍数,所以还需要添加两个字节在最后面,最终占了68个字节!
内存对齐的规则:
1.对于结构的各个成员,第一个成员位于偏移为0的位置,以后的每个数据成员的偏移量必须是 min(系统默认设置的对齐数值,这个数据成员的自身长度)的倍数
2.在所有的数据成员完成各自对齐之后,结构体或联合体本身也要进行对齐,对齐将按照 系统默认指定的数值和结构或者联合体最大数据成员长度中比较小的那个 也就是 min(系统默认对齐数值, 长度最长的数据成员);
内存对齐是操作系统为了快速访问内存而制定的一种规则,有了内存对齐,操作系统进行查找将会快速的多的多!