iOS内存对齐原则

630 阅读2分钟

内存对齐原则:

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

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

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

知道了原则之后,我们现在对这几个原则,逐步分析一下:

结构体分析

struct Struct1 {
    char a;             // 1
    double b;           // 8
    int c;              // 4
    short d;            // 2
} MS1;
struct Struct2 {
    double b;           // 8
    char a;             // 1
    short d;            // 2
    int c;              // 4
} MS2;
struct Struct3 {
    char a;             // 1
    struct Str2 ms2;    // 16
    short d;            // 2
    int c;              // 4
} MS3;

首先我们定义MS1、MS2、MS3这个三个结构体,然后我们来打印结构的size:

NSLog(@"%lu-%lu-%lu", sizeof(MS1), sizeof(MS2), sizeof(MS3));

得到的结果为 24-16-32。

根据上图我们可以知道每个结构体中元素所占字节大小,MS1中的a占1个字节、b占8个字节、c占4个字节、d占2个字节,很明显1+8+4+2 != 24,那为什么MS1的size是24呢?

根据内存对齐原则,a占1字节,b在内存进行占位的时候,由于在a中剩下的7个字节不够b使用,所以b会重新开辟8字节,此时a独占8字节,c接续排在b之后的8字节空间内,c的这块内存在放入c之后还剩余4字节,而d占用2字节,放入c的区域内。所以MS1占用空间为:

8(1)+ 8 + 8(4+2)= 24。

同理,我们可以得到

MS2: 8 + 8(1+2+4)= 16
MS3: 8(1) + 16 + 8(2+4) = 32