C语言程序中union的sizeof输出不符合预期问题咨询
你的Union大小为啥不是预期的18?
嘿,我来帮你理清楚这个问题——你忽略了C语言里内存对齐这个关键规则,这就是实际输出和预期不符的原因。
先搞懂Union的大小计算逻辑
Union的大小规则其实是两条:
- 首先,它至少要能装下最大的那个成员(毕竟所有成员共享同一块内存)
- 其次,这个大小必须是该Union对齐要求的整数倍。对齐要求是取所有成员里最严格的那个(也就是对齐值最大的成员),因为Union的起始地址要满足所有成员的对齐需求。
拆解你的Union成员
咱们按常见的32/64位平台默认数据类型大小来算:
int m[2]:每个int占4字节,总大小8字节,对齐要求是4字节(CPU访问int时需要地址是4的倍数)float n[3]:每个float占4字节,总大小12字节,对齐要求也是4字节char ch[18]:每个char占1字节,总大小18字节,对齐要求1字节(没啥限制)
这里最大的成员是char ch[18],大小18,但最严格的对齐要求是4字节(来自int和float)。
内存对齐怎么影响最终大小?
因为18不是4的整数倍,编译器会自动把Union的大小向上“凑整”到最近的4的倍数——也就是20字节。如果你的平台是8字节对齐(比如某些编译器默认对64位环境设置更严格的对齐),那18会被凑到24字节,这就是你得到意外结果的原因。
怎么验证对齐规则?
你可以在代码里加几行,用C11的_Alignof关键字查看具体的对齐要求:
#include <stdio.h> int main() { union sample { int m[2]; float n[3]; char ch[18]; }u; printf("The size of union = %zu\n", sizeof(u)); // 新增打印对齐信息 printf("Alignof(int) = %zu\n", _Alignof(int)); printf("Alignof(float) = %zu\n", _Alignof(float)); printf("Alignof(union sample) = %zu\n", _Alignof(union sample)); return 0; }
运行后你就能明确自己平台的对齐规则,彻底搞懂大小计算逻辑。
能不能让Union大小是18?
理论上可以通过编译器选项强制取消对齐(比如GCC用-fpack-struct),但非常不建议这么做——内存对齐是为了让CPU高效且正确地访问内存,取消对齐可能导致程序运行变慢甚至崩溃,还会带来兼容性问题。
内容的提问来源于stack exchange,提问作者deepak jha
相关产品推荐
相关产品推荐

