首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C >> 關於C

C語言結構體字節對齊深度解析:巢狀結構體成員的對齊規則

     編輯:關於C

基礎回顧:結構體對齊三原則

  1. 結構體變數首地址為其最寬成員類型大小的整數倍。
  2. 各成員相對結構體起始偏移為自身類型大小的整數倍(必要時填充填充位元組)。
  3. 結構體總大小為最寬成員類型大小的整數倍(尾部填充)。

巢狀結構體成員的對齊實測

案例一

struct s1 { char c1, c2, c3, c4; };  // sizeof = 4
struct s2 { char a; struct s1 s; };  // sizeof = ?

錯誤預期:將 s1 視為整體(4 字節),a 1 字節 + 填充 3 字節 + s1 4 字節 = 8 字節。
實測結果 (GCC/VS2010):sizeof(s2) = 5。

記憶體佈局:

s2: | a (1) | s.c1 (1) | s.c2 (1) | s.c3 (1) | s.c4 (1) |
偏移: 0       1          2          3          4

s 的首地址對齊要求為 char(1 字節),非 4 字節。結構體總長按最寬成員 char 對齊(1 字節),故無尾部填充。

案例二

struct S1 { char a; short b; };  // sizeof = 4 (a+1填充+b)
struct S2 { char a; struct S1 s; };  // sizeof = ?

實測:sizeof(S2) = 6。
佈局:

S2: | a (1) | 3填充 | s.a (1) | 1填充 | s.b (2) |
偏移: 0       1-3      4         5        6-7? 實際 6 字節

s 首地址對齊至 short(2 字節)倍數(偏移 4)。S2 總長對齊至 short(2 字節)倍數 → 6。

對比:非巢狀等效結構

struct S { char a, b; short c; };  // sizeof = 4
// 佈局: a(1) b(1) c(2) → 緊湊無填充

巢狀結構體保持內部佈局不變,作為整體按其最寬成員對齊放入外層結構,而非按巢狀結構體總大小對齊。

歸納結論

  1. 巢狀結構體成員按原有內部佈局展開在外層結構中。
  2. 巢狀成員首地址對齊至該成員內部最寬類型大小的整數倍。
  3. 外層結構體總大小對齊至整個結構體(含巢狀展開)最寬類型大小的整數倍。

硬體視角:為何不按巢狀結構體總大小對齊?

CPU 讀取寬度有限(32 位機單次 4 字節)。強制大結構體按總大小對齊會浪費大量空間,且超過總線寬度仍需多次讀取,收益遞減。編譯器選擇按最寬基本類型對齊,平衡空間與存取效率。

參考資源

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved