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

C/C++ 記憶體對齊完整指南:原理、規則、pragma pack 與實戰計算

     編輯:關於C語言

一、什麼是位元組對齊?

基本型別變數在記憶體中的起始位址必須是其大小的整數倍(address % size == 0)。結構體/類別的對齊值取其成員中最大基本型別大小。這是為了配合 CPU 存取特定位址的硬體需求,提升讀取效率(避免跨邊界讀取需兩次週期)。

二、四大核心概念

概念定義
資料型別自身對齊值sizeof(type),如 char=1, short=2, int/long/float/double=4(32位系統)
結構體/類別自身對齊值所有成員基本型別中最大的自身對齊值(遞迴展開嵌套結構)
指定對齊值#pragma pack(n) 指定的值,預設為編譯器預設值(通常 4/8)
有效對齊值min(自身對齊值, 指定對齊值) —— 最終決定存放位址的關鍵值

三、結構體佈局鐵律

  1. 結構體首位址能被其最寬基本成員大小整除。
  2. 第一個成員偏移量為 0。
  3. 每個成員偏移量必須是其有效對齊值的整數倍,編譯器自動填充 padding。
  4. 嵌套結構體需遞迴展開為基本型別,取最大對齊值處理。
  5. 結構體總大小必須是其有效對齊值的整數倍,尾部必要時填充。
  6. 若 #pragma pack(n) > 自身對齊值,指定值無效,以自身對齊值為準。

四、實戰計算範例

範例 1:無嵌套結構體

#pragma pack(4)
struct TestA {
    int   a;  // offset 0, size 4
    char  b;  // offset 4, size 1
    short c;  // offset 6 (2的倍數), size 2
    char  d;  // offset 8, size 1
}; // 有效大小 9,結構體對齊值=min(4,4)=4 → 總大小 12 (4的倍數)

#pragma pack(2)
struct TestA { ... }; // 總大小 10 (2的倍數)

範例 2:帶嵌套結構體

#pragma pack(2)
struct A { char c; int i; };  // 有效大小 6,自身對齊值=4,有效對齊值=min(4,2)=2 → sizeof(A)=6
struct B { char c1; A s; char c2; }; // 有效大小 9,最寬成員為 A(6),有效對齊值=min(6,2)=2 → sizeof(B)=10

五、替代方案:GCC/Clang 屬性語法

  • __attribute__((aligned(n))):強制對齊到 n 位元組邊界,若成員更大則以成員為準(與 pack 邏輯相反)。
  • __attribute__((packed)):取消優化對齊,按實際大小緊湊排列,等價 #pragma pack(1)。

六、總結與最佳實務

  • 預設對齊通常已足夠,僅在網路封包、硬體暫存器映射、跨平台二進制介面等場景手動調整。
  • 使用 #pragma pack(push, n) / #pragma pack(pop) 保護作用域,避免汙染全域。
  • 記得:對齊犧牲空間換取速度,嵌入式系統需權衡 RAM 限制。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved