內存對齊以及如何關閉內存對齊
阿新 • • 發佈:2018-05-25
內存對齊 關閉 方式 clas 如何 char 以及 範圍 bsp
內存對齊以前有接觸過,最近又碰到好幾次,特整理記錄一下。
首先為什麽需要內存對齊?
內存對齊(memory alignment).為了提高程序的性能,數據結構(尤其是棧)應該盡可能地在自然邊界上對齊。原因在於,為了訪問未對齊的內存,處理器需要作兩次內存訪問;然而,對齊的內存訪問僅需要一次訪問。也就是說“內存對齊”應該是編譯器的管轄範圍,非常依賴平臺。
先來看下面的結構體:
1 struct _Test{ 2 int a; 3 int b; 4 char c; 5 }A;
sizeof(A)=?(32位機器)
在32位機器上,如果內存對齊,sizeof(A)=12。
那麽如何關閉內存對齊呢?
有兩種方式:添加預處理指令 #pragma pack(1) 或者 __attribute__ ((packed))
1 添加預處理指令 #pragma pack(1)
#paragma pack(1)預處理指令的作用是結構體在分配內存時俺一個字節對齊。
1 #include<stdio.h> 2 #pragma pack(1) 3 struct _Test{ 4 int a; 5 int b; 6 char c; 7 }A; 8 void main() 9 { 10 printf("sizeof(A) = %d\n",sizeof(A)); 11 }
輸出結果 就是9。
這裏說明一下,如果用了#paragma pack(1)預處理指令,則整個文件中都會關閉內存對齊,如果只想對其中某個或某幾個結構其關閉呢,這是就要用到第二種方法了。
2 利用__attribute__ ((packed))指令
1 #include<stdio.h> 2 //#paragma pack(1) 3 struct _TestA{ 4 int a; 5 int b; 6 char c; 7 }__attribute__ ((packed))A;8 9 struct TestB{ 10 int a; 11 int b; 12 char c; 13 }B; 14 15 void main() 16 { 17 printf("%d\n",sizeof(A)); 18 printf("%d\n",sizeof(B)); 19 }
輸出結果是 9 12
但是__attribute__ ((packed))這種語法只能在GCC下編譯通過,Visual Sudio不支持這種語法,編譯不過(僅在VS2008測試過,更高版本是否支持沒有測試)。
3. 如果想在Visual Sudio下也能編譯,可以采用下面這種方法
1 #include<stdio.h> 2 3 #pragma pack(push) 4 #pragma pack(1) 5 struct _TestA{ 6 int a; 7 int b; 8 char c; 9 }A; 10 #pragma pack(pop) 11 12 struct TestB{ 13 int a; 14 int b; 15 char c; 16 }B; 17 18 void main() 19 { 20 printf("sizeof(A) = %d\n",sizeof(A)); 21 printf("sizeof(B) = %d\n",sizeof(B)); 22 }
輸出結果是 9 12。
其實就是在不使用默認內存對齊的結構提前加上 #pragma pack(push) #pragma pack(1) ,然後在結束的地方加上 #pragma pack(pop)
內存對齊以及如何關閉內存對齊