在沒有#pragma pack巨集的情況下,要遵守下面的三個原則
1、資料成員對齊規則:結構(struct)(或聯合(union))的資料成員,第乙個資料成員放在offset為0的地方,以後每個資料成員儲存的起始位置要從該成員大小或者成員的子成員大小(只要該成員有子成員,比如說是陣列,結構體等)的整數倍開始(比如int在32位機為4位元組,則要從4的整數倍位址開始儲存。
2、結構體作為成員:如果乙個結構裡有某些結構體成員,則結構體成員要從其內部最大元素大小的整數倍位址開始儲存.(struct a裡存有struct b,b裡有char,int ,double等元素,那b應該從8的整數倍開始儲存.)
3、收尾工作:結構體的總大小,也就是sizeof的結果,.必須是其內部最大成員的整數倍.不足的要補齊.
以下是實戰:
typedef struct bb
bb;typedef struct aa
aa;int main()
;可見,此類實際占用的記憶體空間是9個位元組。根據規則5,結構整體的對齊是min( sizeof( int ), pack_value ) = 4,所以sizeof( testb ) = 12;
例子二:
#pragma pack(2)
class testb
;可見結果與例子一相同,各個成員的位置沒有改變,但是此時結構整體的對齊是min( sizeof( int ), pack_value ) = 2,所以sizeof( testb ) = 10;
例子三:
#pragma pack(4)
class testc
;整個類的實際記憶體消耗是5個位元組,整體按照min( sizeof( short ), 4 ) = 2對齊,所以結果是sizeof( testc ) = 6;
例子四:
struct test
;所以整個結構體的實際記憶體消耗是9個位元組,但考慮到結構整體的對齊是4個位元組,所以整個結構占用的空間是12個位元組。
例子五:
#pragma pack(8)
struct s1
;所以結構體的實際記憶體消耗是8個位元組,結構體的對齊是min( sizeof( long ), pack_value ) = 4位元組,所以整個結構占用的空間是8個位元組。
struct s2
;所以實際記憶體消耗是24自己,整體對齊方式是8位元組,所以整個結構占用的空間是24位元組。
#pragma pack()
所以:sizeof(s2) = 24, s2的c後面是空了3個位元組接著是d。
reference: 和
最後介紹下結構體中的位域。
字面理解位域就是說某些資料元素並不需要佔據一整個位元組,只需要佔據幾位,例如數字8,就只需要佔據乙個位元組的四位即可表示。所謂位域,就是把乙個位元組中的二進位劃分為幾個不同的區域,並說明每個區域的位數。
例如下面的定義:
struct
a; 位域a佔8位,位域b佔2位,位域c佔6位,總共佔據兩個位元組。
關於位域的對齊,有如下幾點:
1. 如果相鄰位域型別相同,位寬之和小於型別的sizeof大小,則後面的字段緊鄰前乙個字段儲存,直到不能容納為止;
2. 如果相鄰位域型別相同,位寬之和大於型別的sizeof大小,則後面的字段將從新的儲存單元開始,其偏移量為其型別大小的整數倍;
3. 如果相鄰位域型別不同,則vc6採取不壓縮方式,dev-c++ 和gcc都採取壓縮方式。依然滿足結構體內存對齊三個原則中的原則1,在不壓縮方式下,如果前乙個位域型別有填充,後面的位域型別和前面的位域型別不相同,則填充的區域不能存放放後面的位域,需另開闢空間;而在壓縮方式下,填充的區域如果可以放下後者位域,則存放,放不下的情況下再另開闢空間。
4.乙個位域必須儲存在同乙個位元組中,不能跨位元組;
5.如乙個位元組所剩空間不夠存放另一位域時,應從下一單元起存放該位域。也可以有意使某位域從下一單元開始。
struct
a;在不壓縮條件下:char型別佔據乙個位元組,而a占用其中兩位;根據原則1,b的型別int佔據四個位元組,應該從4的整數倍處開始存放,所以char後應該填充三個位元組,這三個位元組雖然能夠容納b,但是必須另開空間,再開闢四個位元組的空間存放int,而b佔據四個位元組,後面c的型別和b的型別相同,所以緊鄰b儲存,佔據四個位元組。所以在vc下,sizeof(a) = 8;
壓縮條件下:char型別佔據乙個位元組,而a占用其中兩位;根據原則1,b的型別int佔據四個位元組,應該從4的整數倍處開始存放,所以char後應該填充三個位元組,這三個位元組能夠容納b和c,因此不需要重新開闢空間,直接在這三個位元組上儲存,所以sizeof(a) = 4;
C struct 中位元組對齊問題
c struct 中位元組對齊問題 vc中下面幾個結構體大小分別是多少呢 struct mystruct struct mystruct pragma pack push 儲存對齊狀態 pragma pack 16 設定為16位元組對齊 struct test pragma pack pop 恢復對...
C中位元組對齊問題
好多筆試中,會考結構體的sizeof是多少,這就涉及到了位元組對齊問題。vc或gcc編譯器,預設按4位元組對齊 什麼叫位元組對齊?就是資料在記憶體中存放的方式,它存放的位址需要是它長度的整數倍。比如單位元組放在什麼位址都可以,雙位元組資料只能存放在偶位址上,4位元組數只能存放在是4的倍數的位址上。注...
位元組對齊的問題
為了能使cpu對變數進行高效快速的訪問,變數的起始位址應該具有某些特性,即所謂的 對齊 例如對於4位元組的int型別變數,其起始位址應位於4位元組邊界上,即起始位址能夠被4整除。變數的對齊規則如下 32位系統 type alignment char 在位元組邊界上對齊 short 16 bit 在雙...