为什么需要内存对齐?
内存对齐”应该是编译器的“管辖范围”。编译器为程序中的每个“数据单元”安排在适当的位置上
- 平台原因(移植原因):不是所有的硬件平台都能访问任意地址上的任意数据的;某些硬件平台只能在某些地址处取某些特定类型的数据,否则抛出硬件异常。
- 性能原因:数据结构(尤其是栈)应该尽可能地在自然边界上对齐。原因在于,为了访问未对齐的内存,处理器需要作两次内存访问;而对齐的内存访问仅需要一次访问。
内存对齐的标准是什么?
- 结构(struct)(或联合(union))的数据成员,第一个数据成员放在offset为0的地方,以后每个数据成员存储的起始位置要从该成员大小或者成员的子成员大小(只要该成员有子成员,比如说是数组,结构体等)的整数倍开始(比如int为4字节,则要从4的整数倍地址开始存储。 min(当前开始的位置mn)m=9 n=4
- 结构体作为成员:如果一个结构里有某些结构体成员,则结构体成员要从其内部最大元素大小的整数倍地址开始存储.(struct a里存有struct b,b里有char,int ,double等元素,那b应该从8的整数倍开始存储.)
- 收尾工作:结构体的总大小,也就是sizeof的结果,.必须是其内部最大成员的整数倍,不足的要补⻬。
举例说明
通过图片我们可以知道每个类型占多少字节
截屏2020-09-08 下午7.14.24.png
struct StudentsStruct{
int age;
double score;
short height;
}hfStruct;
通过表以及规则得到下面的答案
struct StudentsStruct{
int age; //4字节 offset=0 [0 1 2 3]
double score; //8字节 必须是8的整数倍(offset(4 5 6 7 ))[8-15]
short height; //2字节 16是2的整数倍 [16 17]
}hfStruct;
//最大字节是8
//实际得到是17
//后面补齐(最大字节的最小整数倍) 所以8的整数倍24
// 计算结构体里面嵌套结构体
//从0开始
typedef struct StudentsStruct{
int age; //4字节 offset=0 [0 1 2 3]
double score; //8字节 必须是8的整数倍[8-15]
short height; //2字节 16是2的整数倍 [16 17]
}hfStruct;
//最大字节是8
//实际得到是17
//后面补齐 8的整数倍24
typedef struct LGStruct1 {
char b; // 1 (0)
double a; // 8 (8 9 10 11 12 13 14 15)
int c; // 4 [16 4] (16 17 18 19)
short d; // 2 [20 2] (20 21)
double f; // 8 [24 25 26 27 28 29 30 31]
hfStruct g; // 24 [32 55] // 56
}struct1;
//最大字节是8
//实际得到是55
//后面补齐 8的整数倍56
// 通过控制台打印可以印证
NSLog(@"%lu-%lu",sizeof(struct1),sizeof(hfStruct));
2020-09-08 19:49:09.091755+0800 001-内存对齐原则[27172:835990] 56-24
通过内存对齐,能让我们在开发中明白什么?
未完成!待续!
网友评论