1. 程式人生 > >結構體的位元組對齊

結構體的位元組對齊

在用sizeof運算子求算某結構體所佔空間時,並不是簡單地將結構體中所有元素各自佔的空間相加,這裡涉及到記憶體位元組對齊的問題。

1) 結構體變數的首地址能夠被其最寬基本型別成員的大小所整除;

2) 結構體每個成員相對結構體首地址的偏移量都是成員大小的整數倍;

3) 結構體的總大小為結構體最寬基本型別成員大小的整數倍。 

型別 int short long char bool float double 指標 列舉
位元組 4 2 4 1 1 4 8 4 4

下面看一下sizeof在計算結構體大小的時候具體是怎樣計算的:

1.test1   空結構體


typedef struct node
{
     
}S;

則sizeof(S)=1。

2.test2

typedef struct node1

{

    int a;

    char b;

    short c;

}S1;

則sizeof(S1)=8。(int)4+(char)1+(填充)1+(short)2=8,且能被(成員最寬型別)4整除。

4.test4  含有靜態資料成員 

typedef struct node3

{

    int a;

    short b;

    static int c;

}S3;

則sizeof(S3)=8。(int)4+(short)2=6+(填充)2=8,能被(成員最寬型別)4整除。

這裡結構體中包含靜態資料成員,而靜態資料成員的存放位置與結構體例項的儲存地址無關(注意只有在C++中結構體中才能含有靜態資料成員,而C中結構體中是不允許含有靜態資料成員的)。

5.test5  結構體中含有結構體

typedef struct node4

{

    bool a;

    S1 s1;

    short b;

}S4;

則sizeof(S4)=16。(bool)1+(填充3)+(S1)8+(short)2=14+(填充)2=16,能被(成員最大寬度S1的寬度)4整除。

S1佔8位元組,而S1中最長資料型別為int,佔4個位元組。

6.test6

若在程式中使用了#pragma pack(n)命令強制以n位元組對齊時,預設情況下n為8。則比較n和結構體中最長資料型別所佔的位元組大小,取兩者中小的一個作為對齊標準。

如果在程式開頭使用命令#pragma pack(4),對於下面的結構體

typedef struct node5

{

    bool a;

    S1 s1;

    double b;

    int c;

}S5;

則sizeof(S5)=24。因為強制以4位元組對齊,而S5中最長資料型別為double,佔8位元組,因此以4位元組對齊。在記憶體中存放方式為:

  |-----------a--------|   4位元組

  |--------s1----------|   4位元組

  |--------s1----------|   4位元組

  |--------b-----------|   4位元組

  |--------b-----------|   4位元組

  |---------c----------|    4位元組