结构体大小不符合预期:为何struct2被编译器填充为6字节?
结构体内存填充与对齐规则解析
先看你的代码:
#include <stdint.h> #include <stdio.h> typedef struct { uint8_t d; uint8_t data[2]; } struct1; typedef struct { uint16_t a; uint8_t d; uint8_t data[2]; } struct2; int main(void) { printf("%u\n", sizeof(struct1)); printf("%u\n", sizeof(struct2)); return 0; }
运行输出:
>./main 3 6
问题根源是编译器的结构体内存对齐规则,它会自动填充内存以满足两个核心要求:
- 结构体中每个成员的起始地址必须是该成员自身大小的整数倍;
- 结构体的总大小必须是其内部最大成员对齐要求的整数倍。
拆解struct1的大小计算
struct1的所有成员都是uint8_t(1字节):
d占1字节,起始地址0;data[2]占2字节,起始地址1;
成员总大小为1+2=3字节。由于最大成员的对齐要求是1字节,3是1的整数倍,无需额外填充,因此sizeof(struct1)=3符合预期。
拆解struct2的大小计算
struct2包含uint16_t(2字节)和uint8_t(1字节)成员:
a是uint16_t,占2字节,起始地址0;d是uint8_t,占1字节,起始地址2;data[2]占2字节,起始地址3;
成员总大小为2+1+2=5字节。但struct2的最大成员是uint16_t,对齐要求为2字节,5不是2的整数倍,因此编译器会在结构体末尾填充1字节,使总大小变为6字节(6是2的整数倍),这就是sizeof(struct2)=6的原因。
简言之,struct1的最大成员对齐要求是1字节,任何大小都能满足;而struct2的最大成员对齐要求是2字节,总大小必须是偶数,所以需要额外填充。
内容的提问来源于stack exchange,提问作者Peter Kapteyn
相关产品推荐
相关产品推荐

