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

C 語言結構體記憶體對齊完整指南

     編輯:關於C語言

為何需要位元組對齊?

  • 硬體存取需求:部分 CPU(如 SPARC、MIPS)要求變數地址必須為其大小的倍數,否則觸發硬體異常。
  • 存取效能:即使 x86 允許非對齊存取,對齊讀取只需一個總線週期,非對齊則需兩次讀取並拼湊,效能大幅下降。

四大核心概念

  1. 資料型別自身對齊值:char=1, short=2, int/float/double=4(32 位系統)。
  2. 結構體自身對齊值:所有成員中最大的自身對齊值。
  3. 指定對齊值:#pragma pack(n) 指定的 n。
  4. 有效對齊值:min(自身對齊值, 指定對齊值)。

對齊規則口訣

  1. 每個成員按有效對齊值偏移,最小化長度。
  2. 巢狀結構體的對齊值取其成員最大對齊值。
  3. 結構體總大小必須為最大有效對齊值的整數倍(尾部填充)。

實戰範例解析

範例 1:#pragma pack(2)

#pragma pack(2)
struct C { char b; int a; short c; };
#pragma pack()
// sizeof(C) = 8
// b@0, a@2(對齊2), c@6, 結構體對齊2, 總長8

若改為 pack(4),a 對齊 4,位移 4,總長 12。

範例 2:巢狀結構體 #pragma pack(8)

#pragma pack(8)
struct S1 { char a; long b; };        // sizeof=8 (b對齊4)
struct S2 { char c; struct S1 d; long long e; };
#pragma pack()
// S2 佈局:c@0, d@4(對齊4), e@16(對齊8, 需填充4字節), 總長24

程式設計策略

省空間:成員由小到大排序

// 差:char, int, char → 12 bytes
// 好:char, char, int → 8 bytes

以空間換時間:顯式預留填充

struct A {
    char a;
    char reserved[3];  // 明確對齊到 4 字節邊界
    int b;
};

隱患與除錯

強制型別轉換風險

unsigned int i = 0x12345678;
unsigned short *p = (unsigned short*)((char*)&i + 1); // 奇數位址
*p = 0; // x86 降速,MIPS/Sparc 崩潰

排查檢查清單

  1. 編譯器 pack 設定(預設通常 8 或 4)。
  2. 目標架構是否支援非對齊存取。
  3. 若不支援,需用特殊修飾符(如 GCC __attribute__((packed)) 或手動處理)。

特殊規則補充

  • static 成員不佔結構體大小。
  • 空結構體/類別大小為 1(確保實例位址唯一)。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved