內存對齊是 C/C++ 程序設計中影響結構體大小、訪問效率乃至跨平台移植的關鍵機制。本文通過具體案例深入剖析 #pragma pack 指令、成員對齊規則、嵌套結構體對齊以及數組對齊特性,幫助開發者精確掌控內存佈局。
min(自身大小, 指定對齊數) 對齊。#pragma pack 指定值)的整數倍,尾部補齊填充字節。#pragma pack(8) // 指定最大對齊數為 8
struct TestStruct4 {
char a; // 1 字節,對齊數 1 → 偏移 0
long b; // 4 字節,對齊數 4 → 偏移 4
}; // 結構體大小 = 8(滿足 8 的倍數)
struct TestStruct5 {
char c; // 1 字節,對齊數 1 → 偏移 0
TestStruct4 d; // 嵌套結構,最大成員對齊數 4 → 偏移 4(補 3 字節)
long long e; // 8 字節,對齊數 8 → 偏移 16(補 4 字節)
}; // 總大小 = 24(滿足 8 的倍數)
#pragma pack() // 恢復默認對齊
關鍵點解讀:
TestStruct4:a 佔 1 字節,b 需 4 字節對齊,故 a 後填充 3 字節,b 從偏移 4 開始,總長 8。TestStruct5:c 後填充 3 字節對齊 d(按 4 字節對齊);d 佔 8 字節(偏移 4~11);e 需 8 字節對齊,故從偏移 16 開始,中間填充 4 字節;最終大小 24 字節。TestStruct4 (8 bytes):
Offset: 0 1 2 3 4 5 6 7
a * * * b b b b (* = padding)
TestStruct5 (24 bytes):
Offset: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
c * * * d.a * * * d.b * * * * * * * e e e e e e e e
(c) (padding) (TestStruct4) (padding) (e)
數組對齊遵循「元素對齊」原則:char a[3] 仍按 1 字節對齊;typedef char Array3[3] 類型對齊數仍為 1,而非數組總長度。但對齊邊界始終為 2 的冪次(1,2,4,8,16…)。
#pragma pack 或使用標準對齊屬性(alignas C11/C++11),保證一致性。掌握內存對齊細節,不僅能優化內存佔用,更能避免因對齊差異導致的難以排查的運行時錯誤,是系統級開發者的必修內功。