结构体成员为结构体时,其对齐方式与大小为何异于原生类型?
结构体成员为结构体类型时的对齐规则解析
核心逻辑:对齐要求≠成员字节大小
结构体的整体对齐要求,由其所有成员中对齐要求最高的成员决定,而非成员的字节大小。这是C标准(如C17 §6.2.8)明确规定的行为,主流编译器均遵循此规则。
逐个分析两个结构体
1. struct S1的对齐与大小计算
struct S1 { uint8_t b1; // 对齐要求:1字节,占用1字节空间 uint16_t w1; // 对齐要求:2字节,占用2字节空间 };
uint16_t的对齐要求为2字节,意味着w1必须从地址为2的倍数的位置开始存储。b1占1字节后,需要填充1字节,才能让w1满足对齐要求。- 结构体整体大小需是自身对齐要求(2字节)的倍数,因此总大小为:
1(b1) + 1(填充) + 2(w1) = 4字节。
2. struct S2的对齐与大小计算
struct W { uint8_t hi; // 对齐要求:1字节 uint8_t lo; // 对齐要求:1字节 }; struct S2 { uint8_t b1; // 对齐要求:1字节,占用1字节空间 struct W w1; // 对齐要求:1字节(因W的最大成员对齐要求为1),占用2字节空间 };
struct W的所有成员都是uint8_t,对齐要求最高为1字节,因此w1的对齐要求是1字节,无需强制从2的倍数地址开始存储。b1占1字节后,w1可以直接紧接其后存储,无需填充。- 结构体整体对齐要求为1字节,总大小
1 + 2 = 3字节,符合1的倍数要求,无需额外填充。
结合输出验证
从地址输出可以直观看到:
struct S1中&s1.w1的地址比&s1.b1大2,中间存在1字节的填充;struct S2中&s2.w1的地址仅比&s2.b1大1,无填充,直接衔接。
内容的提问来源于stack exchange,提问作者dsyx
相关产品推荐
相关产品推荐

