C 语言结构体内存对齐与性能
更新时间:2026-08-26。本文是
languages/c/主题高手层的骨架文档(占位),完整展开将在后续批次补齐。
本文要回答的问题
- 为什么
sizeof(struct)往往比字段之和还大? - 结构体字段怎么排才省内存、快访问?
__attribute__((packed))是银弹吗?代价是什么?
一、对齐规则与 padding
CPU 访问对齐数据是原子的、最快的;跨边界访问可能要读两次。因此编译器在字段之间插入 padding,让每个字段落在"自然对齐"地址上。
c
struct A { char c; int i; }; // sizeof 可能是 8,不是 5| 字段类型 | 自然对齐 | 说明 |
|---|---|---|
char | 1 字节 | 无 padding |
short | 2 字节 | 1 字节起,2 字节对齐 |
int / float | 4 字节 | 4 字节对齐 |
double / 指针 | 8 字节 | 8 字节对齐 |
二、字段重排:同一堆字段,两种体积
把大字段放前面、小字段放后面,可以减少 padding。这是嵌入式与协议解析里的经典优化。
c
struct A { char c; int i; char d; }; // 8 字节(有洞)
struct B { int i; char c; char d; }; // 8 字节(更紧凑)三、packed 与缓存性能
__attribute__((packed))取消 padding:省内存,但非对齐访问变慢、可能 x86 之外崩溃,只在读写外部格式(文件、网络包)时用。- 结构体数组是遍历热点时,字段布局直接影响缓存命中——高频访问字段放同一缓存行,见 缓存与局部性 与 伪共享。
四、与入门层的衔接
- 结构体定义与访问,见 结构体基础、结构体嵌套。
- 联合体共享内存的对齐问题,见 联合体。
- 二进制文件读写时结构体对齐的坑,见 fread/fwrite。
一句话总结
对齐是硬件规则、padding 是编译器补丁:字段按大小降序排能省内存,packed 能换体积但赔上速度,热点结构体的布局就是缓存性能。
本文为骨架文档:核心结构已就位,示例代码与实测数据将在后续批次补齐。