1. 程式人生 > >(Struct)記憶體對齊

(Struct)記憶體對齊

對記憶體對齊的理解:

   (struct)記憶體對齊的規則是:

       1、對於結構的各個成員,第一個成員位於偏移為0的位置,以後每個資料的偏移量必須是Min(編譯器被指定的對齊位元組數,該資料成員的自身長度)的倍數。

GCC中,Min(系統預設(4, 資料成員自身長度(char/short/int/double)

        2、在資料成員完各自對齊之後,結構體(或聯合體)本身也要進行對齊,對齊將按照編譯器被指定的對齊位元組數和結構體(或聯合體)最大資料成員長度中,比較小的那個進行。

GCC中,Min(系統預設(4, struct成員中最大的資料型別(char/short/int/double

)

如:

1

#include <stdio.h>

struct abcd{

char a;

char b;

short c;

char d;

};

int main()

{

printf("sizeof(abcd)=%d/n",sizeof(struct abcd));// 執行結果:sizeof(struct abcd)=6

return 0;

}

      在struct abcd 中,最大的資料型別是short型。所以在資料成員各自對齊後,整個結構體(或聯合體)在進行對齊的時候,按照short型(長度為2)對齊,因為min( 4, short(2) )=2;

再看另一個程式碼:

2

/*2010-09-03*/

#include <stdio.h>

/*32位機器訪問起始地址是4的倍數處的記憶體比較方便

min(系統預設(4),資料成員自身長度)*/

struct node1{//sizeof(struct node1)=8;

char a1;//1

short b1; //2

int c1;//4

};

struct node2{//sizeof(struct node2)=12;

char a2;//1

int c2;//4

short b2; //2

};

struct id_all_char{//

char id3[3]; //3

char ver;//1

char revision;//1

char flag;//1

char size[4]; //4

};

struct idid{

char id3[3];

char ver;

char revision;

char flag;

int size;

}__attribute__((packed));//__attribute__((packed))用於告訴編譯器不要對其進行記憶體對齊!

struct all_short{//sizeof(struct all_short)=6;而不是8!因為a,b,c三個都是short,所以a,b,c最大的資料型別是short,所以min(4,2)=2(short),所以最後整個struct按照short型(長度為2)對齊

short a;//2

short b;//2

short c;//2

};

int main(void)

{

printf("sizeof(struct node1)=%d/nsizeof(struct node2)=%d/n",sizeof(struct node1),sizeof(struct node2));

printf("sizeof(struct all_short)=%d/n",sizeof(struct all_short));

printf("sizeof(struct id_all_char)=%d/n",sizeof(struct id_all_char));

printf("sizeof(struct idid)=%d/n",sizeof(struct idid));

return 0;

}

以下部分,來自網上,這些內容給了我很大的幫助,所以也粘進來了:

二、C++記憶體對齊規則

每個特定平臺上的編譯器都有自己的預設對齊係數”(也叫對齊模數)。程式設計師可以通過預編譯命令#pragma pack(n)n=1,2,4,8,16來改變這一系數,其中的n就是你要指定的對齊係數

對齊規則:

1、資料成員對齊規則:結構(struct)(或聯合(union))的資料成員,第一個資料成員放在offset0的地方,以後每個資料成員的對齊按照 #pragma pack指定的數值和這個資料成員自身長度中,比較小的那個進行。

2、結構(或聯合)的整體對齊規則:在資料成員完成各自對齊之後,結構(或聯合)本身也要進行對齊,對齊將按照#pragma pack指定的數值和結構(或聯合)最大資料成員長度中,比較小的那個進行。

3、結合12推斷:當#pragma packn值等於或超過所有資料成員長度的時候,這個n值的大小將不產生任何效果。

4.各成員變數存放的起始地址相對於結構的起始地址的偏移量必須為該變數的型別所佔用的位元組數的倍數。

5.各成員變數在存放的時候根據在結構中出現的順序依次申請空間,同時按照上面的對齊方式調整位置,空缺的位元組自動填充。

6.同時為了確保結構的大小為結構的位元組邊界數(即該結構中佔用最大空間的型別所佔用的位元組數)的倍數,所以在為最後一個成員變數申請空間後,還會根據需要自動填充空缺的位元組。