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的結果往往都比你宣告的變數總長度要大,這是怎麼回事呢?有人給對齊原則做過總結,具體在 看到現在已記不起來,這裡引用一下前人...