iOS之结构体内存对齐

语言: CN / TW / HK

小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。

内存对⻬的原则

  • 数据成员对⻬规则:结构(struct)或联合(union)的数据成员,第⼀个数据成员放在offset0的地⽅,以后每个数据成员存储的起始位置要从该成员⼤⼩或者成员的⼦成员⼤⼩(只要该成员有⼦成员,例如:数组、结构体等)的整数倍开始\
    • 例如:int4字节,则要从4的整数倍地址开始存储。如果当前开始存储的位置为9,需要空出91011,在12的位置才可存储
  • 结构体作为成员:如果⼀个结构⾥有某些结构体成员,则结构体成员要从其内部最⼤元素⼤⼩的整数倍地址开始存储\
    • 例如:struct a⾥存有struct bb⾥有charintdouble等元素,那b应该从8的整数倍开始存储
  • 收尾⼯作:结构体的总⼤⼩,也就是sizeof的结果,必须是其内部最⼤成员的整数倍,不⾜的要补⻬

案例1

struct LGStruct1 { double a; char b; int c; short d; }struct1; - a8字节,存储在0~7位置 - b1字节,存储在8位置。因为81的倍数,满足条件 - c4字节9~11都不是4的倍数,无法存储,将其空出。所以c存储在12~15位置 - d2字节,存储在16~17位置 - 最后进行收尾⼯作,满足内部最⼤成员的整数倍,补⻬至24

``` NSLog(@"struct1:%lu",sizeof(struct1));


struct1:24 ```

案例2

struct LGStruct2 { double a; int b; char c; short d; }struct2; - a8字节,存储在0~7位置 - b4字节,存储在8~11位置 - c1字节,存储在12位置 - d2字节,13不是2的倍数,无法存储,将其空出。所以d存储在14~15位置 - 最后进行收尾⼯作,满足内部最⼤成员的整数倍,补⻬至16

``` NSLog(@"struct2:%lu",sizeof(struct2));


struct2:16 ```

案例3

struct LGStruct3 { double a; int b; char c; short d; int e; struct LGStruct1 str; }struct3; - a8字节,存储在0~7位置 - b4字节,存储在8~11位置 - c1字节,存储在12位置 - d2字节,13不是2的倍数,无法存储,将其空出。所以d存储在14~15位置 - e4字节,存储在16~19位置 - str为结构体类型,最大成员占8字节。包含结构体成员,从其内部最⼤元素⼤⼩的整数倍地址开始存储。所以str的起始位置为24str结构体内存对齐后占24字节,所以LGStruct3的大小为24 + 24 = 48

``` NSLog(@"struct3:%lu",sizeof(struct3));


struct3:48 ```