CPU 訪問內存以「字」為單位(32 位系統 4 字節,64 位 8 字節)。若數據跨邊界存儲,需兩次總線周期讀取,降低性能。編譯器自動插入**填充字節**使成員按其類型對齊要求對齊。
n,實際對齊 = min(類型大小, n)
struct {
int i; // offset 0, size 4
char j; // offset 4, size 1
int k; // offset 8 (對齊 4), size 4
char r; // offset 12, size 1
int s; // offset 16 (對齊 4), size 4
} // 總計 20 字節,最大對齊 4,20%4=0 ✓
sizeof = 20
struct {
int i; // 0-3
char j; // 4
char r; // 5 (緊湊,char 不需對齊)
int k; // 8 (對齊 4), size 4
int s; // 12, size 4
} // 總計 16 字節
sizeof = 16 —— 連續 char 共享對齊間隙
struct {
double i; // 0-7 (對齊 8)
char j; // 8
char r; // 9
int k; // 12 (對齊 4)
int s; // 16
} // 總計 20 字節,最大對齊 8,20%8=4 → 補齊到 24?實測 20(視編譯器)
實測 sizeof = 20(GCC/MSVC 默認最大對齊 8,但結構體尾部填充以滿足數組元素對齊)
struct {
double i; // 0-7
char j; // 8
int k; // 12 (對齊 4)
char r; // 16
int s; // 20 (對齊 4)
} // 總計 24 字節
sizeof = 24
struct {
double i; // 0-7
char j; // 8
short k; // 10 (對齊 2)
char r; // 12
short s; // 14 (對齊 2)
} // 總計 16 字節,最大對齊 8,16%8=0 ✓
sizeof = 16
offset = 0
for each member:
align = min(sizeof(member), #pragma_pack_value)
offset = (offset + align - 1) / align * align // 向上取整到 align 倍數
member.offset = offset
offset += sizeof(member)
struct_size = (offset + max_align - 1) / max_align * max_align
#pragma pack(1) 壓縮:網絡協議、文件格式、共享內存offsetof 宏驗證:offsetof(Struct, member)alignas/alignof:標準化控制與查詢對齊結構體對齊是空間換時間的編譯器優化。理解規則能精確預測 sizeof、優化內存佈局、避免跨平台坑。面試必考、工程必懂。