一 自然對齊
各個類型自然對齊,即其起始內存地址必須是其類型本身的整數倍。
對於結構體來說,結構體的起始內存地址,必須是結構體中成員最大長度類型的整數倍。
結構體自然對齊應遵守如下規則
1 數據成員對齊規則
在默認情況下,結構體中各成員變量存放的起始地址相對於結構體的起始地址的偏移量:
應該是sizeof(成員變量類型)或者sizeof(成員變量類型)的倍數。
如果結構體中某個成員變量不是基本類型,比如是子結構體,它的起始地址相對於父結構體起始地址的偏移量:
應該是子結構體中最大的基本類型的整數倍。
2 整體對齊規則
結構體占用內存的總大小也有約束條件,為最大的基本類型內存長度的整數倍。
代碼如下:
typedef struct a
{
char c1;
long i;
char c2;
}A
按照自然對齊的規則1:c1與結構體起始地址偏移為0,i偏移為3(必須是i類型long的的倍數),c2偏移為8
按照自然對齊的規則2:現在偏移0-偏移8的9個字節被占用,結構體大小必須是最大成員變量類型long的倍數,所以sizeof(a)為12
typedef struct b
{
char c1;
char c2;
long i;
}B
按照自然對齊的規則1:c1與結構體起始地址偏移為0,c2偏移為1,i偏移為4(必須是i類型long的的倍數),
按照自然對齊的規則2:現在偏移0-偏移7的8個字節被占用,結構體大小必須是最大成員變量類型long的倍數,所以sizeof(a)為8
二 強制對齊
#pragma pack(push) //保存當前對齊狀態
#pragma pack(n) //定義對齊單元大小為n
定義結構體
#pragma pack(pop) //恢復保存的對齊狀態
強制對齊的規則
1 數據成員對齊規則:
n字節對齊是指結構體中成員變量的內存地址與結構體起始地址的偏移量為:
min(sizeof(基本類型), n)的整數倍
2 整體對齊規則:
結構體的總大小也有約束條件:
min(sizeof(基本類型), n)的整數倍
可見,如果設置#pragma pack(1),就等於禁掉了數據對齊。
棧上對齊方式:
在X86平台,棧上對齊方式是整數相關類型按照4字節對齊,浮點數按照8字節對齊;在X64平台,棧上是按照16字節對齊。