1. 程式人生 > >內存對齊以及如何關閉內存對齊

內存對齊以及如何關閉內存對齊

內存對齊 關閉 方式 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)

內存對齊以及如何關閉內存對齊