结构体内存对齐

什么是内存对齐

在说内存对齐之前,我们先看一个例子:

struct Struct1{
    double a;
    char b;
    int c;
    short d;
    }struct1;

struct Struct2{
    double a;
    int b;
    char c;
    short d;
}struct2;

printf("struct1Size:%lu---struct2Size:%lu",sizeof(struct1),sizeof(struct2));

复制代码

下图是各个类型在C和OC中所占字节的大小

截屏2021-06-08 下午3.16.57.png
根据上图的大小我们分别计算struct1和struct2两个结构体的大小分为
8+1+4+2=15和8+4+1+2=15,而我们实际打印出来的结果两个的大小确分别为:24和16,为什么为这样呢,按照常理两个结构体的大小不应该是一样的吗?只是调整一下结构体成员的顺序,却会有两种不同的结果呢?这就是我们要说的内存对齐原则了。

内存对齐原则

1、数据成员对⻬规则:结构(struct)(或联合(union))的数据成员,第一个数据成员放在offset为0的地方,以后每个数据成员存储的起始位置要从该成员大小或者成员的子成员大小(只要该成员有子成员,比如说是数组,结构体等)的整数倍开始(比如int为4字节,则要从4的整数倍地址开始存储。

2、结构体作为成员:如果一个结构里有某些结构体成员,则结构体成员要从其内部最大元素大小的整数倍地址开始存储.(struct a里存有struct b,b里有char,int ,double等元素,那b应该从8的整数倍开始存储.)

3、收尾工作:结构体的总大小,也就是sizeof的结果,.必须是其内部最大成员的整数倍.不足的要补⻬。

这几句话光看字可能不太好理解,用上面两struct1和struct2两个例子来稍微说明一下。

截屏2021-06-08 下午4.31.45.png
根据内存对齐原则第一条原则,第一个成员是在offset为0的位置开始存储,struct1的int类型大小为4个字节,应该是从4的整数倍的位置存储,char的大小为1,后续的第9,10,11三个位置均不能被4整除,故只能从第12的位置开始存储,而第16位是能被2所整除所以可以放在int后面,根据内存对齐第三条原则,结构体的大小应该是能被最大的double的大小也就是8所整除的,需要补位到24,可以得出struct1的大小为24。同理,struct2的int,char位置均能被类型大小所整除,而short的大小为2字节,需要从第14的位置开始存储,根据第三条原则可以得出,当前大小为16是可以被double的大小所整除,最后struct2的大小为16。

第二原则:

struct Struct3 {
    double a;
    int b;
    char c;
    short d;
    int e;
    struct Struct1 str;
}struct3;
复制代码

截屏2021-06-08 下午4.58.35.png
如果结构体里包含结构体成员,根据内存对齐的第二原则,结构体成员要从其内部最大元素大小的整数倍地址开始存储,也就是struct1的存储位置是要从被他最大成员的大小所整除的也就是当前位置要被8整除,存储位置要从第24位开始,struct1的大小为24,可以得出struct3的大小为48。

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享