CC結(jié)構(gòu)體字節(jié)對齊詳解.docx

CC結(jié)構(gòu)體字節(jié)對齊詳解.docx

ID:62033185

大?。?5.71 KB

頁數(shù):3頁

時間:2021-04-15

CC結(jié)構(gòu)體字節(jié)對齊詳解.docx_第1頁
CC結(jié)構(gòu)體字節(jié)對齊詳解.docx_第2頁
CC結(jié)構(gòu)體字節(jié)對齊詳解.docx_第3頁
資源描述:

《CC結(jié)構(gòu)體字節(jié)對齊詳解.docx》由會員上傳分享,免費在線閱讀,更多相關(guān)內(nèi)容在教育資源-天天文庫。

1、C/C++結(jié)構(gòu)體字節(jié)對齊詳解注意:成員對齊有一個重要的條件,即每個成員按自己的方式對齊.其對齊的規(guī)則是,每個成員按其類型的對齊參數(shù)(通常是這個類型的大小)和指定對齊參數(shù)(這里默認是8字節(jié))中較小的一個對齊.并且結(jié)構(gòu)的長度必須為所用過的所有對齊參數(shù)的整數(shù)倍,不夠就補空字節(jié).結(jié)構(gòu)體(struct)的sizeof值,并不是簡單的將其中各元素所占字節(jié)相加,而是要考慮到存儲空間的字節(jié)對齊問題。先看下面定義的兩個結(jié)構(gòu)體.struct{chara;shortb;charc;}S1;struct{chara;charb;s

2、hortc;}S2;分別用程序測試得出sizeof(S1)=6,sizeof(S2)=4可見,雖然兩個結(jié)構(gòu)體所含的元素相同,但因為其中存放的元素類型順序不一樣,所占字節(jié)也出現(xiàn)差異。這就是字節(jié)對齊原因。通過字節(jié)對齊,有助于加快計算機的取數(shù)速度,否則就得多花指令周期。字節(jié)對齊原則結(jié)構(gòu)體默認的字節(jié)對齊一般滿足三個準則:1)結(jié)構(gòu)體變量的首地址能夠被其最寬基本類型成員的大小所整除;2)結(jié)構(gòu)體每個成員相對于結(jié)構(gòu)體首地址的偏移量(offset,即每個成員的起始地址)都是成員自身大小的整數(shù)倍,如有需要編譯器會在成員之間加上

3、填充字節(jié)(internaladding);3)結(jié)構(gòu)體的總大小為結(jié)構(gòu)體最寬基本類型成員大小的整數(shù)倍,如有需要編譯器會在最末一個成員之后加上填充字節(jié)(trailingpadding)。注意:當結(jié)構(gòu)體成員里面有數(shù)組成員時,如inta[10],要看成10個整形變量才參與計算。通過這三個原則,就不難理解上面兩個struct的差異了.對于structS1,為了使short變量滿足字節(jié)對其準則(2),即其存儲位置相對于結(jié)構(gòu)體首地址的offset是自身大小(short占2個字節(jié))的整數(shù)倍,必須在字節(jié)a后面填充一個字節(jié)以對齊

4、;再由準則(3),為了滿足結(jié)構(gòu)體總大小為short大小的整數(shù)倍,必須再在c后面填充一個字節(jié)。對于structS2,卻不必如上所述的填充字節(jié),因為其直接順序存儲已經(jīng)滿足了對齊準則。如果將上面兩個結(jié)構(gòu)體中的short都改為int(占4個字節(jié)),那么會怎么樣呢?程序得出sizeof(S1)=12,sizeof(S2)=8利用上面的準則,也不難計算得出這樣的結(jié)果。S1中在a后面填充3個字節(jié)、在c后面填充3個字節(jié),這樣一共12個字節(jié);S2中在a、b順序存儲之后填充兩個字節(jié)用以對其,這樣一共就8個字節(jié)。當然,在某些時候

5、也可以設(shè)置字節(jié)對齊方式。這就需要使用#pragmapack。#pragmapack(push)//壓棧保存#pragmapack(1)//設(shè)置1字節(jié)對齊struct{chara;shortb;charc;}S1;#pragmapack(pop)//恢復先前設(shè)置如上所示,將對其方式設(shè)為1字節(jié)對齊,那么S1就不填充字節(jié),sizeof為各元素所占字節(jié)之和即4。這一點在從外部2進制文件中讀入struct大小的數(shù)據(jù)到struct中,是很有用的.另外,還有如下的一種方式:·__attribute((aligned(n)

6、)),讓所作用的結(jié)構(gòu)成員對齊在n字節(jié)自然邊界上。如果結(jié)構(gòu)中有成員的長度大于n,則按照最大成員的長度來對齊?!_attribute__((packed)),取消結(jié)構(gòu)在編譯過程中的優(yōu)化對齊,按照實際占用字節(jié)數(shù)進行對齊??战Y(jié)構(gòu)體structS3{};sizeof(S3);//結(jié)果為1“空結(jié)構(gòu)體”(不含數(shù)據(jù)成員)的大小不為0,而是1。試想一個“不占空間”的變量如何被取地址、兩個不同的“空結(jié)構(gòu)體”變量又如何得以區(qū)分呢于是,“空結(jié)構(gòu)體”變量也得被存儲,這樣編譯器也就只能為其分配一個字節(jié)的空間用于占位了。有static

7、的結(jié)構(gòu)體structS4{chara;longb;staticlongc;//靜態(tài)};靜態(tài)變量存放在全局數(shù)據(jù)區(qū)內(nèi),而sizeof計算棧中分配的空間的大小,故不計算在內(nèi),S4的大小為4+4=8。structS5{charc;inti;};structS6{???charc1;???S5s;???charc2};S5的最寬簡單成員的類型為int,S6在考慮最寬簡單類型成員時是將S5“打散”看的,所以S6的最寬簡單類型為int,這樣,通過S6定義的變量,其存儲空間首地址需要被4整除,整個sizeof(S6)的值也

8、應該被4整除。c1的偏移量為0,s的偏移量呢這時s是一個整體,它作為結(jié)構(gòu)體變量也滿足前面三個準則,所以其大小為8,偏移量為4,c1與s之間便需要3個填充字節(jié),而c2與s之間就不需要了,所以c2的偏移量為12,算上c2的大小為13,13是不能被4整除的,這樣末尾還得補上3個填充字節(jié)。最后得到sizeof(S6)的值為16。

當前文檔最多預覽五頁,下載文檔查看全文

此文檔下載收益歸作者所有

當前文檔最多預覽五頁,下載文檔查看全文
溫馨提示:
1. 部分包含數(shù)學公式或PPT動畫的文件,查看預覽時可能會顯示錯亂或異常,文件下載后無此問題,請放心下載。
2. 本文檔由用戶上傳,版權(quán)歸屬用戶,天天文庫負責整理代發(fā)布。如果您對本文檔版權(quán)有爭議請及時聯(lián)系客服。
3. 下載前請仔細閱讀文檔內(nèi)容,確認文檔內(nèi)容符合您的需求后進行下載,若出現(xiàn)內(nèi)容與標題不符可向本站投訴處理。
4. 下載文檔時可能由于網(wǎng)絡(luò)波動等原因無法下載或下載錯誤,付費完成后未能成功下載的用戶請聯(lián)系客服處理。