为何含char*的联合体大小因内存对齐意外变为16字节?
为什么包含
char*的联合体大小从12字节变成了16字节? 原始代码(大小16字节)
struct aa{ float j; char aaa; char bbb; int bb; }aaaa; // sizeof(aaaa) = 12bytes union utag{ char bb; float kk; char *c; struct aa lala; }haha; // sizeof(haha) = 16bytes
注释char*后的代码(大小12字节)
struct aa{ float j; char aaa; char bbb; int bb; }aaaa; // sizeof(aaaa) = 12bytes union utag{ char bb; float kk; //char *c; struct aa lala; }haha; // sizeof(haha) = 12bytes
核心原因:联合体的大小规则
联合体的大小必须同时满足两个条件:
- 能容纳所有成员里体积最大的那个;
- 整体大小是所有成员中最高对齐要求的整数倍。
分步拆解:
struct aa的对齐属性
struct aa的大小为12字节,是因为int bb需要4字节对齐,在char bbb后填充了2字节。而结构体的对齐要求由其内部成员的最高对齐要求决定:struct aa里的float j和int bb都是4字节对齐,因此struct aa的对齐要求是4字节。带
char*的联合体情况
在64位系统中,char*指针的大小是8字节,同时它的对齐要求也是8字节(64位系统下指针类型默认对齐到8字节边界)。此时联合体所有成员的最高对齐要求是8字节,而最大成员struct aa的大小是12字节。
12不是8的整数倍,需要向上取整到最近的8的倍数(16字节),因此联合体的最终大小是16字节。注释
char*后的联合体情况
去掉char*后,联合体成员的最高对齐要求降为4字节(来自float kk和struct aa)。最大成员struct aa的大小是12字节,刚好是4的整数倍,不需要额外填充,因此联合体大小就是12字节。
内容的提问来源于stack exchange,提问作者Hanrabong
相关产品推荐
相关产品推荐

