今天要讲解的是结构体内存的对齐方式。在讲这个之前我们先来了解一下辅助我们可以更好掌握这个知识的一个工具—offsetof
offsetof
它计算的是字节偏移量,即包含指定的成员与其结构开始之间的字节数。
#include <stdio.h>
#include <stddef.h>
struct s1
{
char a;
char b;
int c;
};
int main()
{
struct s1 s;
printf("%d\n",(int)offsetof(struct s1,a));
printf("%d\n",(int)offsetof(struct s1,b));
printf("%d\n",(int)offsetof(struct s1,c));
return 0;
}
这表明了,a相对于起始位置的偏移量为0,b相对于起始位置的偏移量为1,c相对于起始位置的偏移量为4
了解了上述知识后我们再接着来看
struct s1
{
char a;
char b;
int c;
};
int main()
{
struct s1 s;
printf("%d", sizeof(struct s1));
return 0;
}
可以看出struct s1的大小为8个字节
那到底该如何计算呢
- 由上面第二条知,int类型是4个字节对齐与8比4小,所以在这里,c的对齐数是4,c要对齐到4的整数倍也就是4的偏移量的位置,向下数四个字节(同理a,b的对齐数都是1)
2.由第三条知,a,b,c中最大对齐数为4,因此,结构体大小应该是4的倍数而0-7八个字节正好是4的倍数 (如果前面只用了六个字节就要向后再用两个字节,凑够4的倍数也就是最大对齐数的倍数)
struct s1
{
char a;
char b;
int c;
};
struct s2
{
int c1;
struct s1 s;
double c2;
};
由上面,我们不难得出struct s1的大小为8,最大对齐数为4。 double c2的对齐数应该为8,,struct s2的大小应为最大对齐数8的倍数,最后结果为24。大家可以自行算一算。
最后还有一个知识点是设置默认对齐数,默认对齐数可以自己修改
#pragma pack(1)
struct s1
{
char a;
char b;
int c;
};
int main()
{
printf("%d", sizeof(struct s1));
}
#pragma pack(1)
#pragma pack()
struct s1
{
char a;
char b;
int c;
};
int main()
{
printf("%d", sizeof(struct s1));
}
但是一般设置成2的n次方,因为机器读取数据一般是4,8个字节
以上就是结构体内存的对齐方式的讲解。
|