结构体的对齐方式
首先了解:结构体和数组一样都是一块连续的内存空间。
结构体内存对⻬分为3个部分:
1.基本类型数据成员:结构体的第一个数据成员放在偏移量为0的地址,以后每个数据成员存储的起始位置要从该成员大小或者成员的子成员大小的整数倍开始(int为4字节,则要从4的整数倍地址开始存储,哪怕前面有一点空间浪费)。
2.结构体类型数据成员:结构体成员要从其内部最大元素大小的整数倍地址开始存储。(struct a 包含成员 struct b,struct b 的数据成员有有char、int 、double等类型,那b应该从8的整数倍(double的大小)开始存储)。
3.整体字节对齐:结构体的总大小,也就是sizeof的结果必须是其内部最大成员的整数倍,不足的要补⻬。
验证代码:(这里简化了内存编号,实际例如 0x7abc001 等)
struct LGStructOne {
// 8字节,0~7 ,
double a;
// 1字节,9
char b;
// 4字节,12~15
int c;
// 2字节,16~17
short d;
// 总的大小按最大成员所占的8字节进行对齐,所以占24字节
}structOne;
struct LGStructTwo {
// 8字节,0~7
double a;
// 4字节,8~11
int b;
// 1字节,12
char c;
// 2字节,14~15
short d;
// 总的大小按最大成员所占的8字节进行对齐,所以占16字节
}structTwo;
struct LGStructThree {
// 8字节,0~7
double a;
// 4字节,8~11
int b;
// 1字节,12
char c;
// 2字节,14~15
short d;
// 4字节,16~21
int e;
// 24字节,且最大成员占8字节,24~47
struct LGStructOne lgStruct;
// 总的大小按最大成员所占的8字节进行对齐,所以占48字节
}structThree;
int main(int argc, const char * argv[]) {
@autoreleasepool {
// Setup code that might create autoreleased objects goes here.
NSLog(@"\n structOne'size = %lu;\n structOne'size = %lu;\n structOne'size = %lu;\n",
sizeof(structOne),sizeof(structTwo),sizeof(structThree));
}
return NSApplicationMain(argc, argv);
}
/*
structOne'size = 24;
structOne'size = 16;
structOne'size = 48;
*/
Tips: 为什么要从倍数大小开始读取?整数倍内存读取效率更快