C語言字節對齊問題

最近又迴歸到了C,在看一些C的書籍,下面是一個以爲對C字節對齊講得比較詳細的文章。html

原文:C語言字節對齊問題–詳細講解面試

PS:(騰訊實習面試有問到字節對齊有關問題:2015屆騰訊實習校園面試題數組

1、概念
  
   對齊跟數據在內存中的位置有關。若是一個變量的內存地址正好位於它長度的整數倍,他就被稱作天然對齊。好比在32位cpu下,假設一個整型變量的地址爲0×00000004,那它就是天然對齊的。
  
  2、爲何要字節對齊
  
    須要字節對齊的根本緣由在於CPU訪問數據的效率問題。假設上面整型變量的地址不是天然對齊,好比爲0×00000002,則CPU若是取它的值的話須要 訪問兩次內存,第一次取從0×00000002-0×00000003的一個short,第二次取從0×00000004-0×00000005的一個 short而後組合獲得所要的數據,若是變量在0×00000003地址上的話則要訪問三次內存,第一次爲char,第二次爲short,第三次爲 char,而後組合獲得整型數據。而若是變量在天然對齊位置上,則只要一次就能夠取出數據。一些系統對對齊要求很是嚴格,好比sparc系統,若是取未對 齊的數據會發生錯誤,舉個例:
  
  char ch[8];
  char *p = &ch1;
  int i = *(int *)p;
  
  運行時會報segment error,而在x86上就不會出現錯誤,只是效率降低。
  
  3、正確處理字節對齊
  
   對於標準數據類型,它的地址只要是它的長度的整數倍就好了,而非標準數據類型按下面的原則對齊:
  
  數組 :按照基本數據類型對齊,第一個對齊了後面的天然也就對齊了。
  聯合 :按其包含的長度最大的數據類型對齊。
  結構體: 結構體中每一個數據類型都要對齊。
  好比有以下一個結構體:spa

struct stu{
   char sex;
   int length;
   char name[10];
  };
  struct stu my_stu;.net

  因爲在x86下,GCC默認按4字節對齊,它會在sex後面跟name後面分別填充三個和兩個字節使length和整個結構體對齊。因而咱們sizeof(my_stu)會獲得長度爲20,而不是15.
  
  4、attribute選項
  
  咱們能夠按照本身設定的對齊大小來編譯程序,GNU使用attribute選項來設置,好比咱們想讓剛纔的結構按一字節對齊,咱們能夠這樣定義結構體.  設計

struct stu{
   char sex;
   int length;
   char name[10];
  }attribute ((aligned (1)));
  
  struct stu my_stu;
  
  則sizeof(my_stu)能夠獲得大小爲15。
  
  上面的定義等同於
  
  struct stu{
   char sex;
   int length;
   char name[10];
  }attribute ((packed));
  struct stu my_stu;code

  attribute((packed))得變量或者結構體成員使用最小的對齊方式,即對變量是一字節對齊,對域(field)是位對齊.
  
  5、何時須要設置對齊
  
   在設計不一樣CPU下的通訊協議時,或者編寫硬件驅動程序時寄存器的結構這兩個地方都須要按一字節對齊。即便看起來原本就天然對齊的也要使其對齊,以避免不一樣的編譯器生成的代碼不同.htm

相關文章
相關標籤/搜索