gcc 中結構體 struct 記憶體對齊問題分析

2021-05-17 15:37:24 字數 2351 閱讀 8094

每個特定平台的編譯器都有乙個預設的對齊係數,gcc中是4,vc中貌似是8。也可以通過於編譯命令#pragma pack(n)來指定該係數,其中n的值經測試只能是1,2和4.

對齊規則:

1、結構體的第乙個資料成員放在相對位置為0的地方,以後每個資料成員按#pragma pack(n)中n指定的值和該資料成員自身長度中比較小的那個進行對齊。

2、資料成員完成對齊後,結構體本身也要對齊,按照#pragma pack(n)中n的值和結構體資料成員中最長的長度中較小的進行對齊。

驗證(環境:gcc 4.4;sizeof(char)=1;sizeof(int)=4;sizeof(short)=2;sizeof(long)=4;sizeof(long long)=8):

1、預設情況(n=4)

struct st1 {

char ch;//長度1int num;//長度4=n,按4對齊, 4%4=0,起始相對位置=4;存放區間[4,7]

long lv;//長度4=n,按4對齊,8%4=0,起始相對位置=8;存放區間[8,11]

整個結構體成員對齊後所佔的區間為[0,8],佔12個位元組,接著結構體本身對齊,成員中最長的是4,n也等於4,所以結構體本身按4對齊(即對齊係數)。

整個結構體的大小 = 比整個結構體資料成員所佔的總空間大或相等且和對齊係數求模結果為0、與之距離最近的數。

本例中,12%4=0,所以結構體st1佔12個位元組的空間。

2、#pragma pack(1)(即n=1)

struct st1 {

char ch;//長度1=n,按1對齊,0%1=0,起始相對位置=0;存放區間[0]

int num;//長度4>n,按n對齊, 1%1=0,起始相對位置=0;存放區間[1,4]

long lv;//長度4>n,按n對齊,5%1=0,起始相對位置=5;存放區間[5,8]

整個結構體成員對齊後所佔的區間為[0,8],佔9個位元組,接著結構體本身對齊,成員中最長的是4,n等於1,所以結構體本身按1對齊(即對齊係數)。

整個結構體的大小 = 比整個結構體資料成員所佔的總空間大或相等且和對齊係數求模結果為0、與之距離最近的數。

本例中,9%1=0,所以結構體st1佔9個位元組的空間。

3、#pragma pack(2)(即n=2)

struct st1 {

char ch;//長度1int num;//長度4>n,按n對齊, 2%2=0,起始相對位置=2;存放區間[2,5]

long lv;//長度4>n,按n對齊,6%2=0,起始相對位置=6;存放區間[5,8]

整個結構體成員對齊後所佔的區間為[0,8],佔9個位元組,接著結構體本身對齊,成員中最長的是4,n等於2,所以結構體本身按2對齊(即對齊係數)。

整個結構體的大小 = 比整個結構體資料成員所佔的總空間大或相等且和對齊係數求模結果為0、與之距離最近的數。

本例中,10%2=0,所以結構體st1佔10個位元組的空間。

為什麼說#pragma pack(n)中n只能是1,2,4呢?

比如3,如果n=3,在編譯的時候會警告「對齊邊界必須是 2 的較小次方,而不是 3」,也就是說是不起作用的,按預設對齊係數對齊。

4、#pragma pack(8)(即n=8)

struct siz {

char v1;

long long v2;

short v3;

int v4;

如果8起作用,分析一下:

struct siz {

char v1;//長度1long long v2;//長度8=n,按8對齊,8%8=0,起始相對位置=8;存放區間[8,15]

short v3;//長度2int v4;//長度4

整個結構體成員對齊後所佔的區間為[0,23],佔24個位元組,接著結構體本身對齊,成員中最長的是8,n等於8,所以結構體本身按8對齊(即對齊係數)。24%8=0,所以佔24個位元組。

然而,很不幸,執行的結果是20.

接下來,用預設的對齊係數4來分析一下:

struct siz {

char v1;//長度1<4,按1對齊,0%1=0,起始相對位置=0;存放區間[0]

long long v2;//長度8>4,按4對齊,4%4=0,起始相對位置=4;存放區間[4,11]

short v3;//長度2<4,按2對齊,12%2=0,起始相對位置=12;存放區間[12,13]

int v4;//長度4=4,按4對齊,16%4=0,起始相對位置=16;存放區間[16,19]

整個結構體成員對齊後所佔的區間為[0,19],佔20個位元組,接著結構體本身對齊,成員中最長的是8,n等於4,所以結構體本身按4對齊(即對齊係數)。20%4=0,所以佔20個位元組。與執行結果一致。

綜上分析,當n=8的時候gcc仍然使用的是預設的對齊係數4.

gcc 中結構體 struct 記憶體對齊問題分析

每個特定平台的編譯器都有乙個預設的對齊係數,gcc中是4,vc中貌似是8。也可以通過於編譯命令 pragma pack n 來指定該係數,其中n的值經測試只能是1,2和4.對齊規則 1 結構體的第乙個資料成員放在相對位置為0的地方,以後每個資料成員按 pragma pack n 中n指定的值和該資料...

結構體struct記憶體對齊

原因 結構體內存對齊是因為,對於計算機來說讀取4個位元組的記憶體空間比讀取1 2 3個位元組的要更高效。但是也根據編譯器而定,而且自己也可以改變對齊記憶體的大小用 預編譯命令 pragma pack n 規則 1.第乙個元素offset偏移到位址為0的記憶體上。2.之後的元素對齊到對齊數大小的整數倍...

struct結構體的記憶體對齊

1 結構體中第乙個成員在 與結構體變數偏移量為0 的位置 2 其他成員變數要對齊到某個數字 對齊數 的整數倍的位址處 注意 1 對齊數 編譯器預設的乙個對齊數 與 該成員所佔空間的位元組數 的較小值 2 vs中預設的對其數是8,linux中的預設值為4。3 成員對其後,結構體自身也要對齊。結構體的總...