C語言結構體對齊問題詳解

2021-06-18 09:20:00 字數 2096 閱讀 5587

c語言結構體對齊問題詳解

測試環境32位機 winxp:

編譯器vc6(ms cl.exe ) 和 mingw32-gcc-4.5.2

1 結構體資料對齊(沒有#pragma pack()巨集定義)

結構體對齊可以總結為三個基本原則

①資料成員對齊規則:

結構體的資料成員中,第乙個成員從offset為0的位址開始,以後每乙個成員儲存的起始位置為該成員大小的整數倍(在win32中int為32bit也即4位元組對齊)

②結構體作為成員:

如果乙個結構體1作為另乙個結構體2的資料成員,則在結構體2中結構體1要從1內部成員最大的整數倍位址開始儲存。

③結構體的總大小(sizeof):

為該結構體內部最大基本型別的整數倍,不足的要補齊,而不是簡單的所有成員的大小總和。

舉例說明

structa; sizeof(a) = 6;(vc6與gcc相同)

structa; sizeof(a) = 8;(vc6與gcc相同),根據原則③

它的記憶體分配為: a1 a2 a3 a4 , c1 c2 x x(a1為a的第乙個位元組,x為補齊位元組,下同)

structa;

sizeof(a) = 8;

a的記憶體分配為: a1 a2 a3 a4, b1 x c1 c2(原則1)

structa1;

sizeof(a1) = 12; (vc6與gcc相同)

a1的記憶體分配為: a1 x x x, b1 b2 b3 b4, c1 c2 x x

下面是更複雜的情況,結構體作為成員

structa; // sizeof(a) = 24 (vc6與gcc相同)

structb;

sizeof(b) = 48 //(vc6與gcc相同)

a的記憶體分布: a1 a2 a3 a4 x x x x, b1 b2 b3 b4 b5 b6 b7 b7, c1 c2 x x x x x x

b的記憶體分布:a1 b1 x x, c1 c2 c3 c4 , d1 d2 d3 d4 d5 d6 d7 d8, e1 e2 x x x x, a的分布

2 加入#pragma pack()巨集定義)

#pragma pack(1)

上面的ab大小分別為14,30,對應於ab的記憶體分布,去掉x。

pack(2)時為14,30

pack(4)時為16,36

3 結構體的位域

結構體中引入位於是為了壓縮儲存空間。而且位於成員不能單獨計算sizeof。

位域大致有5條基本規則。

① 如果相鄰欄位的型別相同,且位寬之和小於該型別的sizeof(), 則可以緊鄰著前乙個字段儲存,直到不能在容納位置;

structa; // sizeof(a) = 2

記憶體分布: a1 a2 x x, b1 b2 b3 b4, c1 c2 c3 c4 c5 x x x,這裡每乙個代表乙個bit,與上一節不同

structa; // sizeof(a) = 4, 參照後面的原則5

②如果相鄰欄位的型別相同,但是位寬之和大於該型別的sizeof(), 則後面的字段將從新的儲存單元開始儲存,且offset為其型別大小的整數倍;

structa; // sizeof(a) = 2

structa; // sizeof(a) = 8, 同時參照後面的原則5

③如果相鄰位域字段型別不同,各編譯器的處理不同,vc6不壓縮,gcc壓縮。

structa;

sizeof(a) = 12, vc6

sizeof(a) = 4, gcc, 壓縮了為什麼不是3? 同時參照後面的原則5

④如果位域字段之間插入非位域字段,各編譯器的處理不同

structa;

sizeof(a) = 12, vc6

sizeof(a) = 4, gcc, a1 a2 a3 a4 x x x x ,b1~b8, c1 c2 c3 x x x x x

structa;

sizeof(a) = 3, vc6

sizeof(a) = 3, gcc,

⑤整個結構體的總大小為其最寬基本型別的整數倍。

C語言結構體對齊問題詳解

測試環境32位機 winxp 編譯器vc6 ms cl.exe 和 mingw32 gcc 4.5.2 1 結構體資料對齊 沒有 pragma pack 巨集定義 結構體對齊可以總結為三個基本原則 資料成員對齊規則 結構體的資料成員中,第乙個成員從offset為0的位址開始,以後每乙個成員儲存的起始...

C語言結構體對齊問題

結構體對齊規則 預設對齊方式,按結構體的成員中 size 最大的成員對齊。拋開成員size來說,一般情況下32位機器預設4位元組對齊,64位機器預設8位元組對齊。另外可以使用偽指令 pragma pack n 修改預設的位元組對齊。1.使用偽指令 pragma pack n 編譯器將按照 n 個位元...

C語言結構體對齊 記憶體對齊問題

c語言結構體對齊也是老生常談的話題了。基本上是面試題的必考題。內容雖然很基礎,但一不小心就會弄錯。寫出乙個struct,然後sizeof,你會不會經常對結果感到奇怪?sizeof的結果往往都比你宣告的變數總長度要大,這是怎麼回事呢?有人給對齊原則做過總結,具體在 看到現在已記不起來,這裡引用一下前人...