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

深入解析 C 語言結構體記憶體對齊機制

     編輯:關於C語言

什麼是位元組對齊?

在 C 語言中,位元組對齊是指變數在記憶體中的起始位址必須是其佔用位元組數的整數倍。具體來說,若一個變數佔用 n 個位元組,則其起始位址必須滿足 起始位址 % n = 0。對於結構體而言,n 取其成員中佔用空間最大的資料類型大小。

為什麼需要位元組對齊?

雖然記憶體空間以位元組為單位劃分,理論上可從任意位址訪問,但不同 CPU 架構為了提高記憶體訪問速度,規定特定類型的資料只能從特定起始位置訪問。這導致各類資料必須按規則存放,而非單純順序排列。

以 32 位系統為例:若 int 型(4 位元組)存放在偶數位址,CPU 只需一個讀取週期即可讀出;若存放在奇數位址,則需兩個讀取週期並拼湊高低位元組,明顯降低效率。

位元組對齊的具體規則

對齊過程遵循兩大核心原則:

  1. 成員對齊:每個成員按其類型的自身對齊值與指定對齊值(#pragma pack(value))中較小者對齊。自身對齊值通常等於類型大小:char 為 1、short 為 2、int/long/float 為 4、double 為 8。
  2. 結構體整體對齊:結構體總長度必須是所有成員有效對齊值的整數倍,不足則補齊空位元組。

實戰範例解析

假設 #pragma pack(8),分析以下結構體:

struct A { char a; long b; };
  • char a:自身對齊值 1,位址 0x0000 滿足對齊。
  • long b:自身對齊值 4,0x0001 不滿足,補 3 位元組空位,從 0x0004 開始存放,佔 4 位元組。
  • 結構體長度 8,為自身對齊值(4)的 2 倍,符合整體對齊。
    記憶體佈局:a*** b,sizeof(struct A) = 8。

更複雜的巢狀結構體 struct B { char a; struct A b; long c; }:

  • char a:位址 0x0000。
  • struct A b:自身對齊值 4,補 3 位元組,從 0x0004 開始,佔 8 位元組(至 0x000B)。
  • long c:下一位址 0x000C 滿足 4 位元組對齊,佔 4 位元組(至 0x000F)。
  • 總長度 16(0x0010),為自身對齊值 4 的 4 倍。
    佈局:a*** b c,sizeof = 16。

引入 double(對齊值 8)的 struct C 則會觸發更多填充,導致 sizeof = 24。調整成員宣告順序(如 struct E 將 int 置於 struct A 之前)可減少填充,sizeof 從 32 降至 24。

優化建議

  • 成員宣告盡量按類型大小從小到大排序,減少填充空間。
  • 在填充位置顯式宣告 reserved 成員(如 char reserved[3];),提高程式碼可讀性並預留擴展空間。
  • 善用 #pragma pack 控制對齊,但需注意跨平台一致性,網路傳輸結構體時雙端必須約定相同對齊方式。

掌握對齊機制不僅能避免 sizeof 結果出乎意料,更能編寫高效、可移植的系統級程式碼。

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