Note

这个结构体在 32 位系统上占多少字节?

按常见 32 位 ABI 逐步计算含 padding 的结构体大小,并解释为何结果是 20 字节。

省流

题目(32 位操作系统,按常见自然对齐):

struct mystr {
    char a;
    int b;
    char c[10];
};

sizeof(struct mystr) 为 20 字节。
布局是:a 占 1 字节,其后填 3 字节以对齐 int;b 占 4 字节;c[10] 占 10 字节;结构体对齐为 4,末尾再填 2 字节,总和 1+3+4+10+2=20。

计算假设

以下按面试中最常见的 32 位约定:

类型大小对齐
char11
int44
char[10]101

结构体对齐 = 成员最大对齐 = 4。
结构体总大小必须是 4 的整数倍。

逐步排布

偏移 0        : char a            // 1 字节,下一偏移 = 1
偏移 1..3     : padding           // 为让 int 从 4 的倍数开始
偏移 4..7     : int b             // 4 字节,下一偏移 = 8
偏移 8..17    : char c[10]        // 10 字节,下一偏移 = 18
偏移 18..19   : tail padding      // 18 不是 4 的倍数,补到 20

因此:

sizeof = 20

若不加尾部填充,大小会停在 18,则 struct mystr arr[2] 中第二个元素起始偏移为 18,其中的 int b 会落在未按 4 对齐的地址上。尾部填充正是为了保证数组元素仍然满足结构体对齐。

容易算错的点

  • 只把 1 + 4 + 10 = 15 相加,忽略全部 padding。
  • 记得中间 3 字节,却忘了末尾 2 字节,得到 18。
  • 把 64 位下 long/pointer 的对齐习惯套到这道 32 位 int 题上。

验证思路

实际可用编译器打印:

printf("%zu\n", sizeof(struct mystr));

在对应的 32 位目标(或明确相同对齐规则的环境)下,应得到 20。若开启紧凑打包属性,结果可能变小,那已不是本题的默认布局。