小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。
内存对⻬的原则
- 数据成员对⻬规则:结构(
struct
)或联合(union
)的数据成员,第⼀个数据成员放在offset
为0
的地⽅,以后每个数据成员存储的起始位置要从该成员⼤⼩或者成员的⼦成员⼤⼩(只要该成员有⼦成员,例如:数组、结构体等)的整数倍开始\- 例如:
int
为4字节
,则要从4
的整数倍地址开始存储。如果当前开始存储的位置为9
,需要空出9
、10
、11
,在12
的位置才可存储
- 例如:
- 结构体作为成员:如果⼀个结构⾥有某些结构体成员,则结构体成员要从其内部最⼤元素⼤⼩的整数倍地址开始存储\
- 例如:
struct a
⾥存有struct b
,b
⾥有char
、int
、double
等元素,那b
应该从8
的整数倍开始存储
- 例如:
- 收尾⼯作:结构体的总⼤⼩,也就是
sizeof
的结果,必须是其内部最⼤成员的整数倍,不⾜的要补⻬
案例1
struct LGStruct1 {
double a;
char b;
int c;
short d;
}struct1;
复制代码
a
占8字节
,存储在0~7
位置b
占1字节
,存储在8
位置。因为8
是1
的倍数,满足条件c
占4字节
,9~11
都不是4
的倍数,无法存储,将其空出。所以c
存储在12~15
位置d
占2
字节,存储在16~17
位置- 最后进行收尾⼯作,满足内部最⼤成员的整数倍,补⻬至
24
NSLog(@"struct1:%lu",sizeof(struct1));
-------------------------
struct1:24
复制代码
案例2
struct LGStruct2 {
double a;
int b;
char c;
short d;
}struct2;
复制代码
a
占8字节
,存储在0~7
位置b
占4字节
,存储在8~11
位置c
占1字节
,存储在12
位置d
占2
字节,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;
复制代码
a
占8字节
,存储在0~7
位置b
占4字节
,存储在8~11
位置c
占1字节
,存储在12
位置d
占2
字节,13
不是2
的倍数,无法存储,将其空出。所以d
存储在14~15
位置e
占4字节
,存储在16~19
位置str
为结构体类型,最大成员占8字节
。包含结构体成员,从其内部最⼤元素⼤⼩的整数倍地址开始存储。所以str
的起始位置为24
。str
结构体内存对齐后占24字节
,所以LGStruct3
的大小为24 + 24 = 48
NSLog(@"struct3:%lu",sizeof(struct3));
-------------------------
struct3:48
复制代码