结构体联合体sizeof内存求值 - 对齐数
讲解下struct和union的内存求值和对齐
以题目讲解
结构体联合体sizeof内存求值 - 对齐数
不同位数下类型字节大小
一定要搞清楚编辑器,一般编辑器中的类型字节如图:
类型 | 16位平台 | 32位平台 | 64位平台 |
char | 1个字节 | 1个字节 | 1个字节 |
short | 2个字节 | 2个字节 | 2个字节 |
int | 2个字节 | 4个字节 | 4个字节 |
unsigned int | 2个字节 | 4个字节 | 4个字节 |
float | 4个字节 | 4个字节 | 4个字节 |
double | 8个字节 | 8个字节 | 8个字节 |
long | 4个字节 | 4个字节 | 8个字节 |
long long | 8个字节 | 8个字节 | 8个字节 |
unsigned long | 4个字节 | 4个字节 | 8个字节 |
指针 | 2个字节 | 4个字节 | 8个字节 |
一般我使用的是64位的编译器,下面来看看对齐规则
内存对齐规则
规则
- 结构体的第一个成员直接对齐到相对于结构体变量起始位置为
0
处偏移。 - 从第二个成员开始,要对齐到某个【对齐数】的整数倍的偏移处。
- 结构体的总大小,必须是最大对齐数的整数倍。每个结构体成员都有一个对齐数,其中
最大的对齐数就是最大对齐数
。 - 如果嵌套了结构体的情况。嵌套的结构体对齐到自己的最大对齐数的整数倍处,结构体的整体大小就是所有最大对齐数(含嵌套结构体的对齐数)的整数倍。
struct 内存对齐求值
- 举例:struct内存求值
#include <stdio.h>
#pragma pack(16)
struct BBB {long num;char ha;short ba[5];
}b;int main() {printf("%d\\n", sizeof(b.num));//8printf("%d\\n", sizeof(b.ha)); //1printf("%d\\n", sizeof(b.ba)); //10 ,short大小是2//最大对齐数是8printf("%d\\n", sizeof(BBB));return 0;
}//这里ba数组的最大对齐数是2,因为short大小2小于定义的对齐数16//sizeof(BBB)=8+1+1+(2*5)=20,这里的1是为了让ba数组对齐到2的倍数
//但是对齐规则里面有个结构体的总大小,必须是最大对齐数的整数倍
//这里最大对齐数是8,也就是结果需要是8的倍数,最终等于sizeof(BBB)=24
嵌套struct内存对齐求值
- 如果有嵌套结构体呢 :
#include <stdio.h>
#pragma pack(16)
struct BBB {long num;char ha;short ba[5];struct BBB2{int s; //4int ba2[5]; //20 char ha2[2]; //2}b2; //4+20+2=26。对齐=4的倍数=28
}b;int main() {printf("%d\\n", sizeof(b.num));//8printf("%d\\n", sizeof(b.ha)); //1printf("%d\\n", sizeof(b.ba)); //10 ,short大小是2printf("%d\\n",sizeof(b.b2));//28,见上面//最大对齐数是8printf("%d\\n", sizeof(BBB));return 0;
}
//sizeof(BBB)=8+1+1+(2*5)=20,后面嵌套的BBB2最大对齐数是4,对齐大小是28,所以从4的倍数出发,这里是20开始,正好,sizeof(BBB)=20+28=48,正好是8的倍数
union的内存大小求值
解释下union的内存大小求值
union大小计算准则
1、至少要容纳最大的成员变量
2、必须是所有成员变量类型大小的整数倍 —— 记住是成员变量类型 char c[7]算 1
- 举例:求sizeof(union)
#include<stdio.h>//联合体
union u2
{char a; //1int b; //4short c; //2double d; //8int e[5]; //20
}U3;//主函数
int main(){ printf("%d\\n",sizeof(U3));//输出24return 0;
}
struct嵌套union内存对齐求值
#include <stdio.h>
#pragma pack(16)
struct BBB {int num;//4char ch; //1char pa[3]; //3union {int a; //4float b; //4} myUnion;//这个union内存大小等于4
}b;int main() {printf("%d\\n", sizeof(b));//4+1+3+4=12 ; 到char pa[3]时候这时候正好到地址8,然后union的内存是4,对齐数,要求是它的整数倍所以正好从8开始,最终结果12。满足是对齐数4,1,4的倍数return 0;
}
其他内容见专栏的结构体和联合体的文章
如果有啥补充的后续更新