iOS底层 - 内存字节对齐规则

iOS开发底层探究之路

本篇文章将从探究结构体(struct)的内部字节对齐来了解iOS内存中字节是怎样对齐的。
首先我们来看看各种数据类型在32位和64位操作系统下的大小规则:

字节对齐规则

1.结构体(struct)(或联合(union))的数据成员,第一个属于成员放在offset为0的地方,
  以后每个数据成员存储的起始位置要从该成员大小或者成员的字成员大小
  (只要该成员有子成员,比如说是数组,结构体等)的整数倍数开始(比如int为4字节,则要从4的整数备注地址开始存储)。
2.结构体作为成员:如果一个结构里嵌套某些结构体成员,则结构体成员要从其内部最大元素大小的整数倍地址开始存储。
  (struct a 里存有struct b,b 里有 char,int , double等元素,那b 应该从8 的整数倍开始存储)
3.收尾工作:结构体的总大小,也就是sizeof的结果,必须是其内部最大成员大小的整数倍,不足的要补齐。

例子讲解-结构体

typedef struct {
    char a;
    int b;
    char c;
} AStruct;

sizeof(AStruct) = 12

从offset为0开始,char 大小为1,所以a-->[0]
然后按序往后,int 大小为4,所以找到后面的4(4是第一个为4的整数倍),从4开始,4,5,6,7。所以b --> [4,5,6,7].
然后来到了8位置,因为char 大小为1,所以c-->[8].
可以看出,AStruct占用9字节,最后AStruct的大小要满足是最大成员int大小4的整数倍,往后延续,就是12,如上图所示,从0 到 11 即是AStruct的存放排布。

typedef struct {
    char a;
    int b;
    char c;
    double d;
} BStruct;

sizeof(BStruct) = 24

BStruct 跟上面的 AStruct 前三个排布情况是一样的,当我们来到d时候,因为double 大小为8,所以要找c的位置8 之后数字为 8的整数倍的16,往后延续8字节,来到了23,此时可知BStruct所占有大小为24字节,而且此时24正好是成员最大的8的整数倍,所以0到23 即为BStruct的排布情况。

结构体内嵌结构体

typedef struct {
    char a;       //1
    char c;       //1
    int b;        // 4
} AStruct;

typedef struct {
    char a;
    AStruct A;
    char c;
} BStruct;

sizeof(AStruct) = 8;
sizeof(BStruct) = 16;

下图展示BStruct的排布情况:

AStruct 大小为8,AStruct里面成员最大的是int 为 4, 所以BStruct 对应的A 从4的位置开始 ,增加8,来到了11 ,然后c -->[12].
满足文章开头所说的嵌套结构体的规则。最后得出BStruct大小为 4的整数倍 16.

typedef struct {
    char a;       //1
    char c;       //1
    int b;        // 4
    double d;  //8
} AStruct;

typedef struct {
    char a;
    AStruct A;
    char c;
} BStruct;

sizeof(AStruct) = 16;
sizeof(BStruct) = 32;

下图展示BStruct的排布情况:


如图所示,a-->[0]
AStruct中成员最大的为8,所以往后找8的倍数,得出A-->[8,23]
c-->[24]
所以BStruct的总大小为32.因为要满足8的整数倍。(BStruct内嵌的AStruct的成员最大为double 8)

正如文章开头的规则所说,结构体作为结构体成员,其对齐值取其自身成员中最长数据类型的成员的长度。

你可能感兴趣的:(iOS底层 - 内存字节对齐规则)