前言
C语言中比较常用的构造类型,无疑是结构体了,在使用结构体的过程中,结构体大小的问题一直被大家关注。
对于结构体中只有基本类型时的对齐规则,网上的资料说的很全面,大家自行参考即可,我就不在这里赘述了,本文重点说一下,结构体中包含结构体时的对齐规则。
正文
这里以32位系统为例。
注意下面的两个例子:
例1:
struct A{
short a;
short b;
short c;
};
struct B{
struct A a;
char c;
int d;
};
printf("%d\n",sizeof(struct B));//--输出 12
例2:
struct A{
short a;
short b;
short c;
char d;
};
struct B{
struct A a;
char c;
int d;
};
printf("%d\n",sizeof(struct B));//--输出 16
分析
对于例1,貌似是将 struct A 中的三个short在结构体B中做了拆分,然后按照int 4字节对齐,前2个short占4字节,第三个short和后面的char占4字节,int自己占4字节,一共12字节。
对于例2,如果按照例1中的逻辑,将struct A 拆分,1个short两个char连续存储,刚好占用4字节,总大小应该也是12啊,怎么就16了呢????貌似是将struct A 作为一个整体放在了struct B中,按4字节对齐,struct A字节占用8字节,然后char c占用4个字节,最后的int 再占用4个字节,一共16个字节。
那么内结构体 究竟是要拆分 还是作为整体呢?
是作为整体。
对于例1:
struct A 本来是按照short 2字节对齐的,struct A 本身就是6个字节,但是将他放在struct B中时,是由于struct B中是按照int 4字节对齐,所以需要struct B给struct A 分出2个字节的空间用来凑4字节对齐,这2个字节是由struct B提供的,所以struct B中的成员可以占用,也就是struct B中的那个char可以占用,所以一共是12个字节。
对于例2:
struct A 按照short 2字节对齐,struct A本身的大小是8字节,也就是说struct A最后的那个char后面有1个字节的空间,但是注意,这1个字节的空间是由于struct A自身对齐产生的,是属于struct A的,所以将struct A放入struct B中时,虽然struct B中有一个char,但是没法占用struct A中剩余的那1个字节的空间,只能再分配一个4字节用来存储,存储后剩下3字节又不够存储后面的int了,再分配4个字节用来存储int,所以总计是16个字节。
总结
结构体中包含结构体时,内结构体是被当做整体的。但是需要注意,有没有因为外结构体的对齐,导致给内结构体变量多分了空间,多分了,可以占用;没有多分,就不能占用内结构体的“闲置”空间。