前言
struct LGTruct1{
double a;
char b;
int c;
short d;
}struct1;
复制代码
struct LGTruct1{
double a;
int b;
char c;
short d;
}struct2;
复制代码
NSLog(@"%lu-%lu",sizeof(struct1),sizeof(struct2));
输出打印大小为 24-16;这就引起了我们的思考,为什么两个结构体都有相同的成员变量,但输出的内存大小确不一样。想要弄清楚这个问题先了解下面几个方面的知识。
各类型C和OC类型所占字节
内存对齐原则
1.数据成员对齐规则:结构(struct)(或联合(union))的数据成员,第一个数据成员放在offset为0的地方,以后每个数据成员存储的起始位置要从该成员大小或者成员的子成员大小(只要该成员有子成员,比如说是数组,结构体等)的整数倍开始(比如int在 32 位机为4字节,则要从4的整数倍地址开始存储。
2.结构体作为成员:如果一个结构体里有某些结构体成员,则结构体成员要从其内部最大元素大小的整数倍地址开始存储.(struct a里存有struct b,b里有char,int ,double等元素,那b应该从8的整数倍开始存储.)
3.收尾工作:结构体的总大小,也就是sizeof的结果,必须是其内部最大成员的整数倍.不足的要补齐。
例子分析
struct LGStruct3{
double a; //8字节 [0-7]
int b; //4字节 [8-11]
char c; //2字节 [12-13]
short d; //2字节 [14 15]
int e; //4字节 [16 17 18 19]
struct LGTruct1 str;
}struct3;
复制代码
下面分析结构体LGTruct1;结构体成员要从其内部最大元素大小的整数倍地址开始存储 LGTruct1最大元素大小为8;24为8的整数倍,所以24开始存;
struct LGTruct1{
double a; //8字节[24 31]
char b;//2字节 [32 33]
int c; //4字节 从4字节的整数倍开始[36 39]
short d; //2字节 [40 41]
}struct1;
复制代码
double a 结构体嵌套类型分析根据内存对齐原则1 第一个数据成员放在offset 0的位置 先存double a 8字节 就是[o-7]存double a;
int b ; 4字节 结构体成员要从内部最大元素大小的整数倍地址开始存储,[8]是4的整数倍,所以 [8 9 10 11]
char c; 2字节 [12-13]
short d; 2字节 [14 15]
int e; 4字节 [16 17 18 19]
double a; //8字节[24 31]
char b;//2字节 [32 33]
int c; //4字节 从4字节的整数倍开始[36 39]
short d; //2字节 [40 41]
收尾工作:结构体的总大小,也就是sizeof的结果,必须是其内部最大成员的整数倍.不足的要补齐。
结果 48为8的整数倍
NSLog(@"%lu",sizeof(struct3));
结果为48;
总结
内存对齐苹果有一套制定的规则,目的是为了提升存储的效率和读取的安全性,另外苹果会对内存存储进行了相应的算法优化,减少了读取次数的同时确保读取安全性。