1. 程式人生 > >C/C++中的位元組對齊

C/C++中的位元組對齊

在C/C++中使用sizeof()計算結構體所佔記憶體時獲得的位元組數並不是每個成員變數的所佔位元組大小的和,如定義結構體A
struct A
{
int a1;
char a2;
};
sizeof(A)返回的值為8,而不是sizeof(int)+sizeof(char)=5
另外結構體成員變數的順序不同,結構體所佔的記憶體大小可能也不一樣,定義結構體B
struct B
{
char b1;
int b2;
char b3;
};
sizeof(B)返回的值為12,但是如果將b1和b2定義的順序交換,則會得到不同的值
struct C
{
int b2;
char b1;
char b3;
};

sizeof(C)返回的值為8,這些都是因為位元組對齊機制導致的。

處理器讀取對齊的資料比讀取不對齊的資料速度要快,因此編譯器會將這些資料在記憶體中對齊,位元組數小於對齊位元組數的變數後面會填充多出的位元組。

對齊位元組數以結構體成員變數中位元組數最大的為準,在結構體A,B,C中都是以int所佔位元組數4為對齊位元組數,他們在記憶體中的分佈如下:

結構體A的記憶體分佈


結構體B的記憶體分佈


結構體C的記憶體分佈


結構體成員變數按定義的順序分佈在記憶體中,如果兩個或兩個以上相鄰成員變數的位元組數都小於對齊位元組數並且位元組數之和也小於對齊位元組數,則這兩個變數分佈在同一對齊資料塊內,如結構體C中的b1和b3位元組數之和為2,小於sizeof(int)=4,所以b1和b3分佈在同一資料塊的相鄰位元組,sizeof(C)=8。而結構體B中的b1和b3不相鄰,所以b1和b3單獨佔據4位元組的記憶體塊,sizeof(B)=12。
合理安排成員變數型別和順序可以減少結構體所佔記憶體位元組數,例如把佔位元組數大的放在前面,佔位元組數小的放在後面。

注:如果不想使用位元組對齊或者想自定義位元組對齊方式可使用#pragma pack (n),指定對齊位元組數為n,當n=1的時候成員變數緊湊排列在記憶體中,也就是沒有使用位元組對齊,如果未指定n值則恢復預設對齊方式。