字節對齊--結構體數據類型的存儲

研究問題:

  1. 什麼是字節對齊?
  2. 爲什麼要字節對齊?
  3. 怎樣字節對齊?

要點:

  • 一個變量佔用 n 個字節,則該變量的起始地址必須能夠被 n 整除,即: 每個變量的起始存放地址 % n = 0,
      對於結構體,這個 n 取其成員種的數據類型佔空間的值最大的那個。

      即:A1存儲地址addr1%A1對齊值=0,A2按順序後延,如果下一個地址addr2%A2!=0就補空,後移存儲地址addr3。若addr3%A2!=0,繼續後移。
      同時,每個內存塊爲最大的對齊值N,不滿的要補空。

  • 內存空間是按照字節來劃分的,從理論上說對內存空間的訪問可以從任何地址開始,但是在實際上不同架構的CPU爲了提高訪問內存的速度,就規定了對於某些類型的數據只能從特定的起始位置開始訪問。這樣就決定了各種數據類型只能按照相應的規則在內存空間中存放,而不能一個接一個的順序排列。

      舉個例子,比如有些平臺訪問內存地址都從偶數地址開始,對於一個int型(假設32位系統),如果從偶數地址開始的地方存放,這樣一個讀週期就可以讀出這個int數據,但是如果從奇數地址開始的地址存放,就需要兩個讀週期,並對兩次讀出的結果的高低字節進行拼湊才能得到這個int數據,這樣明顯降低了讀取的效率。

  • 每個成員按其類型的對齊參數(通常是這個類型的大小)和指定對齊參數(不指定則取默認值)中較小的一個對齊,並且結構的長度必須爲所用過的所有對齊參數的整數倍,不夠就補空字節。
      這個規則有點苦澀,可以把這個規則分解一下,前半句的意思先獲得對齊值後與指定對齊值進行比較,其中對齊值獲得方式如下:
     1. 數據類型的自身對齊值爲:對於char型數據,其自身對齊值爲1,對於short型爲2,對於int, long, float類型,其自身對齊值爲4,對於 double 類型其自身對齊值爲8,單位爲字節。
     2.結構體自身對齊值:其成員中自身對齊值最大的那個值。
    其中指定對齊值獲得方式如下:

#pragma pack (value)時的指定對齊值value

  未指定則取默認值。
  後半句的意思是主要是針對於結構體的長度而言,對於結構體,它可能使用了多種數據類型,那麼這句話翻譯成對齊規則: 每個成員的起始地址 % 自身對齊值 = 0,如果不等於 0 則地址後移直到符合規則,前面的補空達到對齊值。
  換句話說,對於結構體而言,結構體在在內存的存放順序用如下規則即可映射出來:
 (一)單獨的每個成員的起始地址 % 每個成員的自身對齊值 = 0,如果不等於 0 就後移,前面補空使得每個成員內存塊爲結構體中最大的對齊值。
 (二)結構體的長度必須爲結構體的自身對齊值的整數倍,不夠就補空字節。

來自 http://www.51hei.com/bbs/dpj-43246-1.html


截圖展示區:

  1. 32位編譯器下:
    舉例:
typedef struct 
{
 char aa;
 short ab;
 char ac;
 long ad;
}A;

  sizeof(A) 結果爲: 12 內存位置爲: $*$$ $*** $$$$ 注意:每個成員首地址必須爲自身對齊值的整數倍。
2.

typedef struct 
{
 long ba;
 short bb;
 long bc;
 char bd;
 short be;
}B;

sizeof(B)結果爲:16 內存位置爲:$$$$ $$** $$$$ $*$$
3.

typedef struct 
{
 char ca;
 char cb;
 short cc;
 char cd;
 short ce;
 A cf; 
 char cg;
 short ch;
 long ci;
}C;

sizeof(C)結果爲:28 內存位置爲:$$$$ $*$$ $*$$ $**** $$$$ $*$$ $$$$
來自 http://www.51hei.com/bbs/dpj-43246-1.html

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章