小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。
内存对⻬的原则
- 数据成员对⻬规则:结构(
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