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

C 語言結構體內存對齊詳解:從基本原理到實戰計算

     編輯:關於C

前言:為什麼 sizeof 不等於成員大小之和?

[c]
struct student {
    char name[20];
    int age;
    char sex;
    char phone[15];
};
// sizeof = 40? 實際 44
// 若 phone[16] -> sizeof = 44? 實際 48

這就是**內存對齊**在作祟。CPU 訪問內存時,按字長(4/8 字節)對齊能顯著提升效率,編譯器自動插入填充字節。

核心規則

  1. 對齊基準:結構體中**基本類型**(非數組/結構體)的最大尺寸。如 int 4 字節 → 4 字節對齊;double 8 字節 → 8 字節對齊。
  2. 成員對齊:每個成員相對結構體起始地址的偏移量,必須是該成員大小的整數倍(或對齊基準的整數倍,取較小者)。
  3. 整體對齊:結構體總大小必須是對齊基準的整數倍,尾部填充。
  4. 嵌套結構體:以嵌套結構體中**最大基本類型**為準,而非嵌套結構體總大小。

經典案例逐步推演

案例 1:基本類型混合

[c]
struct A { char c; double d; char ch; };
// 最大基本類型 double(8) -> 對齊基準 8
// c: offset 0, size 1
// d: offset 8 (對齊到 8), size 8
// ch: offset 16, size 1
// 總大小 24 (尾部填充到 24,24%8==0)

案例 2:調整順序省空間

[c]
struct B { double d; char c; char ch; };
// d: offset 0, size 8
// c: offset 8, size 1
// ch: offset 9, size 1
// 總大小 16 (c/ch 共用一個 8 字節槽,尾部填充到 16)

結論:將大類型集中放置、小類型聚合,可減少填充,節省內存。

案例 3:數組與結構體

[c]
struct score { float eng, math, comp; }; // 基本類型 float(4),對齊基準 4,大小 12
struct student {
    char name[10];  // 數組,非基本類型
    int age;        // 基本類型 int(4)
    char sex;       // 基本類型 char(1)
    struct score s; // 嵌套結構體,最大基本類型 float(4)
};
// 對齊基準 = max(int, float) = 4
// 逐個計算偏移,最終 sizeof = 28 (或 32 視編譯器)

案例 4:聯合體

[c]
union U { int i; char c; char str[9]; };
// 聯合體大小 = 最大成員(9) -> 對齊到 4 的倍數 = 12
struct S { int i; char c; char str[9]; };
// 結構體大小 = 4+1+9=14 -> 對齊到 4 的倍數 = 16

實用技巧:#pragma pack 強制對齊

[c]
#pragma pack(push, 1)  // 1 字節對齊(緊湊模式)
struct Packed { char c; int i; };
#pragma pack(pop)
// sizeof = 5,但訪問 i 可能觸發非對齊訪問異常(ARM)或性能下降(x86)

適用場景:網絡協議報文、文件格式、共享內存——需精確控制佈局,且確認目標平台支援非對齊訪問。

總結速查表

場景對齊基準總大小規則
基本類型結構體最大基本類型尺寸尾部填充至基準整數倍
含數組/嵌套結構體所有基本類型中最大者同上,嵌套體內部自行對齊
聯合體最大成員尺寸向上取整至基準整數倍
調整成員順序不變可減少填充,節省空間
#pragma pack(n)min(n, 類型自身對齊)緊湊佈局,慎用
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved