C语言结构体sam大小为何是40字节而非计算的29字节?
问题解答:C语言结构体大小与手动计算不符的原因
这是内存对齐导致的——编译器会自动在结构体成员之间或末尾添加填充字节,让CPU的内存访问更高效,下面具体分析:
先明确编译器默认对齐规则(以常见64位GCC为例)
- 每个成员的起始地址必须是「自身类型对齐值」的整数倍:char对齐1字节,int/float对齐4字节,double对齐8字节。
- 结构体总大小必须是「结构体最大成员对齐值」的整数倍,不足的话在末尾补填充字节。
逐个分析你的结构体布局
1. struct stfloat 实际大小是16字节,不是12字节
你定义的struct stfloat {float f4; double f5;}:
- float f4占4字节,但double f5要求起始地址是8的整数倍,所以f4后面会被编译器自动补4字节填充。
- 加上double f5的8字节,总大小为4+4+8=16字节。
2. union f13 的大小是16字节
union的大小取其内部最大成员的大小,你定义的struct stint是12字节,struct stfloat是16字节,因此union f13的大小为16字节。
3. struct sam 最终大小为40字节的计算过程
我们拆解每个成员的内存占用:
char utype:占1字节,下一个成员是float(要求对齐到4字节),所以补3字节填充,这部分共4字节。float f6 + float f7:各占4字节,合计8字节,满足对齐要求。double f8:占8字节,对齐到8字节地址,无额外填充。union f13:占16字节,对齐到8字节地址,无额外填充。- 此时总和为4+8+8+16=36字节,但
struct sam的最大对齐值是8(来自double类型),36不是8的倍数,因此在末尾补4字节填充,最终总大小为40字节。
关于你看到的「char占4字节、float占8字节」的误解
你通过指针看到的是成员起始地址到下一个成员的地址差,并非成员本身的大小:
utype本身大小仍是1字节(sizeof(utype)输出1可证明),只是后面补了3字节填充,所以地址差为4。f4本身是4字节,只是struct stfloat中f4后面补了4字节填充,导致f4到f5的地址差为8,并非f4占8字节。
内容的提问来源于stack exchange,提问作者HOUCH_1234
相关产品推荐
相关产品推荐

