結構體成員對齊等問題

struct的成員對齊
1 自然對界
struct 是一種複合數據類型,其構成元素既可以是基本數據類型(如int、long、float 等)的變量,也可以是一些複合數據類型(如array、struct、union 等)的數據單元。對於結構體,編譯器會自動進行成員變量的對齊,以提高運算效率。缺省情況下,編譯器爲結構體的每個成員按其自然對界(natural alignment)條件分配空間。各個成員按照它們被聲明的順序在內存中順序存儲,第一個成員的地址和整個結構的地址相同。
自然對界(natural alignment)即默認對齊方式,是指按結構體的成員中size 最大的成員對齊。注:這裏的最大指整形數據,實型,結構體成員不在此例。見後面實例程序
例如:
struct naturalalign
{
char a;
short b;
char c;
};
在上述結構體中,size 最大的是short,其長度爲2 字節,因而結構體中的char 成員a、c 都以2 爲單位對齊,sizeof(naturalalign)的結果等於6;
如果改爲:
struct naturalalign
{
char a;
int b;
char c;
};
其結果顯然爲12。
再來看如下代碼:

typedef union {long i; int k[5]; char c;} DATE;
struct data { int cat;  double dog;} too;
struct data2 { char cat; int dag;} tt;
struct data3 { char cat; double dag;} ;
struct data4 { char cat; DATE dag;} ;
struct data5 { char cat; unsigned short int dag;};
struct data6 { int cat; unsigned short int dag;};
struct data7 { char cat; char *dag;};
struct data8 { char cat; unsigned short int dag;int a;};
struct data9 { char cat; int a;unsigned short int x;};
struct data10 { int cat; unsigned short int dag;char a;};
void main(void)
{
  DATE max;
  printf("%d\n",sizeof(struct data));//輸出12,其中雙精度實型爲8字節,是按四個字節對齊,估整型也按4字節對齊
  printf("%d\n",sizeof(struct data2));//輸出8,其中整型爲4字節,按四個字節對齊,字符型按4字節對齊
  printf("%d\n",sizeof(struct data3));//輸出12,其中雙精度實型爲8字節,按四個字節對齊,字符型按4字節對齊
  printf("%d\n",sizeof(struct data4));//輸出24,其中聯合體爲20字節,按四個字節對齊,字符型按4字節對齊
  printf("%d\n",sizeof(struct data5));//輸出4,其中短整型爲2字節,按2個字節對齊,字符型按2字節對齊
  printf("%d\n",sizeof(struct data6));//輸出8,其中整型爲4字節,按四個字節對齊,短整型按4字節對齊
  printf("%d\n",sizeof(struct data7));//輸出8,其中所有指針在內存均佔4字節,按四個字節對齊,估短整型按4字節對齊
  printf("%d\n",sizeof(struct data8));//輸出8,爲保證a按四個字節對齊,前面必須也是四字節對齊,dag剛好爲2字節,估char後必須留出1字節的空間,這樣就是8字節。
printf("%d\n",sizeof(struct data9));//輸出12,爲保證num按四個字節對齊,char後必須留出3字節的空間;同時爲保證整個結構的自然對齊(這裏是4字節對齊),在x後還要補齊2個字節,這樣就是12字節。
printf("%d\n",sizeof(struct data10));//輸出8,
  printf("%d\n",sizeof(struct data)+sizeof(max));//輸出32,其中聯合體爲20字節,sizeof(struct data)爲12字節
}


2 指定對界
一般地,可以通過下面的方法來改變缺省的對界條件:
· 使用僞指令#pragma pack (n),編譯器將按照n 個字節對齊;
· 使用僞指令#pragma pack (),取消自定義字節對齊方式。
注意:如果#pragma pack (n)中指定的n 大於結構體中最大成員的size,則其不起作用,結構體
仍然按照size 最大的成員進行對界
例如:
#pragma pack (n)
struct naturalalign
{
char a;
int b;
char c;
};
#pragma pack ()
當n 爲4、8、16 時,其對齊方式均一樣,sizeof(naturalalign)的結果都等於12。而當n 爲2
時,其發揮了作用,使得sizeof(naturalalign)的結果爲6
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章