本次試驗是在32位系統(tǒng)下進行的。
一、什么是內(nèi)存對齊
現(xiàn)代計算機中內(nèi)存空間都是按照byte劃分的,從理論上講似乎對任何類型的變量的訪問可以從任何地址開始,但實際情況是在訪問特定變量的時候經(jīng)常在特定的內(nèi)存地址訪問,這就需要各類型數(shù)據(jù)按照一定的規(guī)則在空間上排列,而不是順序的一個接一個的排放,這就是對齊。
為什么要了解內(nèi)存對齊:各個硬件平臺對存儲空間的處理上有很大的不同。一些平臺對某些特定類型的數(shù)據(jù)只能從某些特定地址開始存取。其他平臺可能沒有這種情況,但是最常見的是如果不按照適合其平臺要求對數(shù)據(jù)存放進行對齊,會在存取效率上帶來損失。比如有些平臺每次讀都是從偶地址開始,如果一個int型(假設為32位系統(tǒng))如果存放在偶地址開始的地方,那么一個讀周期就可以讀出,而如果存放在奇地址開始的地方,就可能會需要2個讀周期,并對兩次讀出的結(jié)果的高低字節(jié)進行拼湊才能得到該int數(shù)據(jù)。顯然在讀取效率上下降很多。這也是空間和時間的博弈。
通常我們不需要去主動進行內(nèi)存對齊的操作,編譯器會自動為我們選擇最優(yōu)的對齊規(guī)則方式,合理利用空間節(jié)省程序運行的時間,但若是我們能了解這種規(guī)則,對于我們編寫程序還是會有很大的幫助的。
二、對齊內(nèi)存規(guī)則
1.第一個成員在與結(jié)構(gòu)體變量偏移量為0的地址處。
2.其他成員變量要對齊到對齊數(shù)(編譯器默認的一個對齊數(shù)與該成員大小的較小值)的整數(shù)倍的地址處。
3.結(jié)構(gòu)體總大小為最大對齊數(shù)(除了第一個成員每個成員變量都有一個對齊數(shù))的整數(shù)倍。
4.如果嵌套了結(jié)構(gòu)體的情況,嵌套的結(jié)構(gòu)體對齊到自己的最大對齊數(shù)的整數(shù)倍處,結(jié)構(gòu)體的整體大小就是所有最大對齊數(shù)(含嵌套結(jié)構(gòu)體的對齊數(shù))的整數(shù)倍。
三、實例解釋
要想要看出數(shù)據(jù)的對齊方式,首先你就得明白各種數(shù)據(jù)類型在各種操作系統(tǒng)下所占字節(jié)的大小。
我們來看一下在32位系統(tǒng)下各種參數(shù)類型所占字節(jié)的大?。?/p>
接著我們用幾個例子來講解對齊規(guī)則:
(1)
首先我們用一字節(jié)對齊的方式來檢驗我們之前所說的類型所占字節(jié)大?。?/p>
1 #pragma pack(1)//讓編譯器對此結(jié)構(gòu)體作字節(jié)對齊 2 struct A 3 { 4 char a;// 1 5 int b;// 4 6 short c;// 2 7 long d;// 4 8 float e;// 4 9 };10 #pragma pack()//取消字節(jié)對齊,回復默認字節(jié)對齊11 int main()12 {13 struct A a;14 printf("%d\n&q