結(jié)構(gòu)體內(nèi)存對齊問題

結(jié)構(gòu)體內(nèi)存對齊問題

ID:6693130

大?。?3.50 KB

頁數(shù):8頁

時間:2018-01-22

結(jié)構(gòu)體內(nèi)存對齊問題_第1頁
結(jié)構(gòu)體內(nèi)存對齊問題_第2頁
結(jié)構(gòu)體內(nèi)存對齊問題_第3頁
結(jié)構(gòu)體內(nèi)存對齊問題_第4頁
結(jié)構(gòu)體內(nèi)存對齊問題_第5頁
資源描述:

《結(jié)構(gòu)體內(nèi)存對齊問題》由會員上傳分享,免費在線閱讀,更多相關(guān)內(nèi)容在學術(shù)論文-天天文庫。

1、結(jié)構(gòu)體內(nèi)存對齊問題結(jié)構(gòu)體內(nèi)存對齊問題.txt偶爾要回頭看看,否則永遠都在追尋,而不知道自己失去了什么。男人掏錢是戀人關(guān)系,女人掏錢是夫妻關(guān)系,男女搶著掏錢是朋友關(guān)系。男人愛用眼睛看女人,最易受美貌迷惑;女人愛用心看男人,最易受傷心折磨。當在C中定義了一個結(jié)構(gòu)類型時,它的大小是否等于各字段(field)大小之和?編譯器將如何在內(nèi)存中放置這些字段?ANSIC對結(jié)構(gòu)體的內(nèi)存布局有什么要求?而我們的程序又能否依賴這種布局?這些問題或許對不少朋友來說還有點模糊,那么本文就試著探究它們背后的秘密。首先,至少有一點可以肯定

2、,那就是ANSIC保證結(jié)構(gòu)體中各字段在內(nèi)存中出現(xiàn)的位置是隨它們的聲明順序依次遞增的,并且第一個字段的首地址等于整個結(jié)構(gòu)體實例的首地址。比如有這樣一個結(jié)構(gòu)體:structvector{intx,y,z;}s;int*p,*q,*r;structvector*ps;p=&s.x;q=&s.y;r=&s.z;ps=&s;assert(p

3、。唔,對不起,ANSIC沒有做出保證,你的程序在任何時候都不應(yīng)該依賴這個假設(shè)。那這是否意味著我們永遠無法勾勒出一幅更清晰更精確的結(jié)構(gòu)體內(nèi)存布局圖?哦,當然不是。不過先讓我們從這個問題中暫時抽身,關(guān)注一下另一個重要問題————內(nèi)存對齊。許多實際的計算機系統(tǒng)對基本類型數(shù)據(jù)在內(nèi)存中存放的位置有限制,它們會要求這些數(shù)據(jù)的首地址的值是某個數(shù)k(通常它為4或8)的倍數(shù),這就是所謂的內(nèi)存對齊,而這個k則被稱為該數(shù)據(jù)類型的對齊模數(shù)(alignmentmodulus)。當一種類型S的對齊模數(shù)與另一種類型T的對齊模數(shù)的比值是大于

4、1的整數(shù),我們就稱類型S的對齊要求比T強(嚴格),而稱T比S弱(寬松)。這種強制的要求一來簡化了處理器與內(nèi)存之間傳輸系統(tǒng)的設(shè)計,二來可以提升讀取數(shù)據(jù)的速度。比如這么一種處理器,它每次讀寫內(nèi)存的時候都從某個8倍數(shù)的地址開始,一次讀出或?qū)懭?個字節(jié)的數(shù)據(jù),假如軟件能保證double類型的數(shù)據(jù)都從8倍數(shù)地址開始,那么讀或?qū)懸粋€double類型數(shù)據(jù)就只需要一次內(nèi)存操作。否則,我們就可能需要兩次內(nèi)存操作才能完成這個動作,因為數(shù)據(jù)或許恰好橫跨在兩個符合對齊要求的8字節(jié)內(nèi)存塊上。某些處理器在數(shù)據(jù)不滿足對齊要求的情況下可能會

5、出錯,但是Intel的IA32架構(gòu)的處理器則不管數(shù)據(jù)是否對齊都能正確工作。不過Intel奉勸大家,如果想提升性能,那么所有的程序數(shù)據(jù)都應(yīng)該盡可能地對齊。Win32平臺下的微軟C編譯器(cl.exefor80x86)在默認情況下采用如下的對齊規(guī)則:任何基本數(shù)據(jù)類型T的對齊模數(shù)就是T的大小,即sizeof(T)。比如對于double類型(8字節(jié)),就要求該類型數(shù)據(jù)的地址總是8的倍數(shù),而char類型數(shù)據(jù)(1字節(jié))則可以從任何一個地址開始。Linux下的GCC奉行的是另外一套規(guī)則(在資料中查得,并未驗證,如錯誤請指正

6、):任何2字節(jié)大小(包括單字節(jié)嗎?)的數(shù)據(jù)類型(比如short)的對齊模數(shù)是2,而其它所有超過2字節(jié)的數(shù)據(jù)類型(比如long,double)都以4為對齊模數(shù)。現(xiàn)在回到我們關(guān)心的struct上來。ANSIC規(guī)定一種結(jié)構(gòu)類型的大小是它所有字段的大小以及字段之間或字段尾部的填充區(qū)大小之和。嗯?填充區(qū)?對,這就是為了使結(jié)構(gòu)體字段滿足內(nèi)存對齊要求而額外分配給結(jié)構(gòu)體的空間。那么結(jié)構(gòu)體本身有什么對齊要求嗎?有的,ANSIC標準規(guī)定結(jié)構(gòu)體類型的對齊要求不能比它所有字段中要求最嚴格的那個寬松,可以更嚴格(但此非強制要求,VC7

7、.1就僅僅是讓它們一樣嚴格)。我們來看一個例子(以下所有試驗的環(huán)境是IntelCeleron2.4G+WIN2000PRO+vc7.1,內(nèi)存對齊編譯選項是"默認",即不指定/Zp與/pack選項):typedefstructms1{chara;intb;}MS1;假設(shè)MS1按如下方式內(nèi)存布局(本文所有示意圖中的內(nèi)存地址從左至右遞增):_____________________________

8、

9、

10、

11、a

12、b

13、

14、

15、

16、+---------------------------+Bytes:14因為MS1中有最強對齊要

17、求的是b字段(int),所以根據(jù)編譯器的對齊規(guī)則以及ANSIC標準,MS1對象的首地址一定是4(int類型的對齊模數(shù))的倍數(shù)。那么上述內(nèi)存布局中的b字段能滿足int類型的對齊要求嗎?嗯,當然不能。如果你是編譯器,你會如何巧妙安排來滿足CPU的癖好呢?呵呵,經(jīng)過1毫秒的艱苦思考,你一定得出了如下的方案:_______________________________________

18、

19、\\\\

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

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

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