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

C 語言結構體內存字節對齊完整指南

     編輯:關於C

對齊的作用與原因

  • 硬件平台對內存訪問有對齊要求(如 ARM 某模式下非對齊訪問觸發異常)
  • 非對齊訪問需多次總線周期拼湊數據,嚴重降低效率
  • 對齊讓 CPU 單周期讀取完整數據類型

四大核心概念

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

對齊規則

  1. 每個成員按有效對齊值對齊,偏移量為有效對齊值的整數倍
  2. 結構體總大小為最大有效對齊值的整數倍(尾部填充)
  3. 嵌套結構體按其自身對齊值對齊

實例詳解

例 1:#pragma pack(2)

#pragma pack(2)
struct C {
    char b;   // 偏移 0, 大小 1
    int a;    // 有效對齊 2, 偏移 2, 大小 4 (佔 2,3,4,5)
    short c;  // 有效對齊 2, 偏移 6, 大小 2 (佔 6,7)
}; // 總大小 8 (最大有效對齊 2 的倍數)
#pragma pack()

改為 pack(4) 時 a 偏移 4,總大小 12。

例 2:嵌套結構體

#pragma pack(8)
struct S1 { char a; long b; }; // 大小 8 (b 對齊 4, 尾部填充 3)
struct S2 {
    char c;          // 偏移 0
    struct S1 d;     // 對齊 4, 偏移 4, 大小 8
    long long e;     // 對齊 8, 偏移 16, 大小 8
}; // 總大小 24 (最大有效對齊 8 的倍數)
#pragma pack()

編程策略

節省空間:成員按類型大小遞增排序

// 差:大小交替,產生大量填充
struct Bad { char a; int b; char c; short d; }; // 12-16 字節

// 優:小類型聚集
struct Good { char a; char c; short d; int b; }; // 8-12 字節

顯式填充:以空間換時間

struct Aligned {
    char a;
    char reserved[3]; // 顯式填充,文檔化對齊意圖
    int b;
};

隱患與排查

  • 強制類型轉換:(unsigned short*)(p+1) 從奇地址訪問 short,x86 降速,MIPS/Sparc 崩潰
  • 網絡/文件序列化:直接傳輸結構體極危險,必須逐字段序列化

問題排查清單

  1. 檢查編譯器 pack 設置
  2. 確認目標架構是否支持非對齊訪問
  3. 若不支持,檢查是否有特殊修飾符(如 GCC __attribute__((packed)))
  4. 使用 offsetof 驗證成員偏移
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved