C 結構體內存對齊

2021-06-21 13:44:55 字數 1534 閱讀 8293

最近工作時需要用到記憶體對齊,查了資料。發現比較亂且觀點不一,因此驗證並總結。下面所寫都是在實際中得到驗證。

環境:xp,vc6.0.

記憶體對齊又稱位元組對齊,可以加快系統的處理速度。在結構體中的儲存中尤其重要,那麼系統對齊是按照什麼方式呢?

每個特定平台上的編譯器都有自己的預設

「對齊係數」(也叫對齊模數)。比如32位windows平台下,vc預設是按照

8bytes對齊的(vc->project->settings->c/c++->code 

generation中的truct 

member 

alignment 值預設是8),程式設計師可以通過預編譯命令#pragma pack(n),n=1,2,4,8,16來改變這一係數,其中的n就是你要指定的「對齊係數」。

這個是系統設定的對齊係數,實際的對齊係數是結構體的成員自身長度的最大值和系統設定係數的較小者。比較拗口,舉例說明

struct strtest ;

對於這個結構體最大的成員長度是8(d),假設系統設定的是4,那麼實際對齊係數就是4.如果沒有成員c,d,那麼實際對齊係數就是2.

下面所講的都是針對實際對齊係數,簡稱n。

首先說一下結構體內存對齊規則:

1.結構體的首位址必須是n的整數倍。

2.對於每乙個成員來說,相對首位址的偏移量必須是成員長度和n的較小者的倍數。

3.結構體的總大小必須是n的整數倍,不足後面進行補充。

下面就舉例驗證這3個規則:

#include

typedef struct

strtest1;

int main()

其中系統設定對齊系數字4,執行結果如上圖所示,首先測試了char,short,int,double,字元陣列的長度以及整個結構體的長度。

在得到n之前先說一下陣列,由於陣列是在記憶體空間聯絡排列的,因此針對陣列可拆成乙個乙個的基本型別看待。因此n=min(8,4)=4

結構體的首位址位1245028為4的倍數,首位址也是成員a的位址,成員b根據規則2所以首位址1245030-1245028=2(2/2=1),後面的成員以此按照規則2.

最後總大小位28是4的整數倍,因此不用補充。

如果系統設定對齊系數字8時,執行結果如下圖所示

n=min(8,8)=8.首位址1245024是8的倍數。成員位置和上面分析類似,總大小位2+2+4+8+10=28不是8的倍數,因此補充為32.

上面說道陣列作為結構體成員,如果是結構體變數作為成員呢?

規則4:結構體變數作為結構體的成員時,以整體看待。舉例如下:

#include

typedef struct 

strtest;

typedef struct

strtest2;

int main()

其中系統設定對齊系數字8,執行結果如下

從結果可以看到strtest所佔大小是16,這也符合我們上面的分析。n=min(16,8)=8

首位址1245000是8的倍數。第二個成員的大小是16大於8,按照8對齊,因此位址為1245008,cde比較好分析,f要注意規則2.

C結構體內存對齊

struct mystc 這樣的乙個結構體多大?反正不是1 4 2位元組。在記憶體中,結構體內的元素分布不是緊挨著依次排布的,而是存在著 記憶體對齊 因為硬體原因,讀取記憶體要按照一定的偏移量來儲存,那麼儲存資料也相應按照一定的偏移量儲存,也就是相應元素型別的長度。所以在記憶體中,每個元素都 以為 ...

結構體內存對齊

結構體內存對齊 一 什麼是位元組對齊,為什麼要對齊?現代計算機中記憶體空間都是按照byte劃分的,從理論上講似乎對任何型別的變數的訪問可以從任何位址開始,但實際情況是在訪問特定型別變數的時候經常在特 定的記憶體位址訪問,這就需要各種型別資料按照一定的規則在空間上排列,而不是順序的乙個接乙個的排放,這...

結構體內存對齊

一 什麼是位元組對齊,為什麼要對齊?現代計算機中記憶體空間都是按照byte劃分的,從理論上講似乎對任何型別的變數的訪問可以從任何位址開始,但實際情況是在訪問特定型別變數的時候經常在特 定的記憶體位址訪問,這就需要各種型別資料按照一定的規則在空間上排列,而不是順序的乙個接乙個的排放,這就是對齊。對齊的...