在訪問記憶體時,如果位址是按4位元組對齊,則訪問效率會高很多。這種現象的原因在於訪問記憶體的硬體電路。一般情況下,位址匯流排總是按照對齊後的位址來訪問。例如,你想得到0x00000001開始的四位元組內容,系統首先需要以0x00000000讀四位元組,從中取得3位元組,然後再用0x00000004作為開始位址,獲得下乙個4位元組,再從中得到第乙個位元組,再次組合出需要得到的內容。但是,如果位址從一開始就是對齊到0x00000000,則系統只要一次讀寫即可。
考慮到效能方面,編譯器會對結構進行對齊處理。
二、c++位元組對齊的規則
在沒有使用#pragma pack的情況下,位元組對齊大致有以下三條規則:
1.資料成員對齊規則:struct, union的資料成員,第乙個資料成員放在offset為0的地方,之後的資料成員的儲存起始位置都是放在該資料成員大小的整數倍位置。如在32bit的機器上,int的大小為4,因此int儲存的位置都是4的整數倍的位置開始儲存。
2.結構體作為資料成員的對齊規則:在乙個struct中包含另乙個struct,內部struct應該以它的最大資料成員大小的整數倍開始儲存。如 struct a 中包含 struct b, struct b 中包含資料成員 char, int, double,則 struct b 應該以sizeof(double)=8的整數倍為起始位址。
3.收尾工作的對齊規則:整個struct的大小,應該為最大資料成員大小的整數倍。
例如:定義如下類:
class myclass
;
執行如下**:
myclass myclass;
printf("0x%08x\n", &myclass.a);
printf("0x%08x\n", &myclass.b);
printf("0x%08x\n", &myclass.c);
輸出結果如下:
可以看到myclass類裡邊變數a和c是int型別,b是char型別,a在記憶體中開始的位址是4的倍數,雖然b只占用乙個位元組,但是為了滿足c記憶體位址的開始是4的倍數,b和c之間有三個位元組的記憶體單元沒有被占用。
在vc中,使用pack預處理指令來調整位元組對齊的規則。
使用#pragma pack(n),指定c編譯器按照n個位元組對齊;
定義如下類:
class myclass
;
執行如下**:
int _tmain(int argc, _tchar* argv)
在未使用#pragma pack()時,輸出結果為:
使用#pragma pack()後,輸出結果為:
C語言 位元組對齊(記憶體對齊)
1 平台原因 移植原因 不是所有的硬體平台都能訪問任意位址上的任意資料,某些硬體平台只能在某些位址處取某些特定型別的資料,否則丟擲硬體異常 2 硬體原因 經過記憶體對齊之後,cpu的記憶體訪問速度大大提公升。1.對齊原則 原則1 資料成員對齊規則 結構 struct 或聯合 union 的資料成員,...
C語言記憶體位元組對齊
在c語言面試和考試中經常會遇到記憶體位元組對齊的問題。今天就來對位元組對齊的知識進行小結一下。首先說說為什麼要對齊。為了提高效率,計算機從記憶體中取資料是按照乙個固定長度的。以32位機為例,它每次取32個位,也就是4個位元組 每位元組8個位,計算機基礎知識,別說不知道 位元組對齊有什麼好處?以int...
c 中的記憶體位元組對齊
最近遊戲專案開發中遇到一件麻煩事,客戶端unity開發用的c 但需要呼叫c 中的函式進行訊息加密,呼叫dll中的介面時,c 中的結構體需要傳入到c 中進行操作,但是由於c 中的訊息頭定義的比較苟且,沒有提供乙個跟c 中一一對應的結構體,導致加密後再解密出錯,最後發現是記憶體位元組對齊的問題,在c 訊...