在結構體的定義中,經常遇到位元組對齊的問題,尤其是在網路程式中。
一、什麼是位元組對齊?
在計算乙個結構體的sizeof值時,並不是簡單了計算結構體各成員的大小的和,而應考慮到各成員間和整個結構體的位元組對齊問題。
如struct s
;sizeof(struct s)的結果並不是1+4+2=7,而是1+3+4+2+2=12, 其中的3和第二個2就是填充位元組的大小。
二、為什麼要位元組對齊?
提高cpu讀寫記憶體的效率,從而提公升系統效能。
三、預設對齊原則
預設的對齊原則為:
1) 結構體的首位址能夠被其最寬基本型別成員的大小所整除;
2) 結構體成員相對結構體的偏移量必須是成員型別大小的整數倍,否則進行填充直至是整數倍;
3) 結構體的大小必須為最大基本型別成員的大小的整數倍,否則在最後乙個成員後進行填充,直至是整數倍。
以前面的struct s結構體為例
成員ch,char型,偏移量為0,預設對齊大小為1;
成員i, int型,偏移量為1,預設對齊大小為4, 1 % 4 不等於0,則進行填充,這裡需要填充3個位元組(填充的是隨機值)
成員j, short int型, 偏移量為8,預設對齊大小為2, 8 % 2 等於0。 但此時整個結構體大小為1+3+4+2=10,不是4的整數倍。所以,需要在j的後面填充2個位元組。
四、更改預設對齊
#pragma pack(n) // 設定n個位元組對齊
#pragma pack() //取消n個位元組對齊
當使用pragma pack指定對齊位元組大小,每個成員確定對齊大小時,取成員型別大小和指定對齊大小的較小值(若預設對齊大小被改變,則只須考慮按指定對齊位元組對齊)。
測試1:
#pragma pack(2)
struct s
;#pragma pack()
則sizeof(struct s) = 1+1+4+2 = 8
測試2:
#pragma pack(2)
struct s
;#pragma pack()
則sizeof(struct s) = 1+1+4 = 6
五、策略
在定義結構體時,應注意位元組對齊的問題,特別是在網路應用程式中。因此,定義結構體時,應按成員型別大小從小到的順序定義,如果實在有填充位元組,可將填充位元組部分定義為reserved欄位。
結構體位元組對齊
include pragma pack 2 struct t.pragma pack int main int argc,char argv 最後輸出的結果為 8。這個表示是按照2位元組來對齊資料,首先分配2位元組給成員變數i,分配完成後,還剩一位元組,zj add補0 沒法容納成員變數d,此時會再...
結構體位元組對齊
include pragma pack 2 struct t.pragma pack int main int argc,char argv 最後輸出的結果為 8。這個表示是按照2位元組來對齊資料,首先分配2位元組給成員變數i,分配完成後,還剩一位元組,zj add補0 沒法容納成員變數d,此時會再...
結構體位元組對齊
在用sizeof運算子求算某結構體所佔空間時,並不是簡單地將結構體中所有元素各自佔的空間相加,這裡涉及到記憶體位元組對齊的問題。從理論上講,對於任何 變數的訪問都可以從任何位址開始訪問,但是事實上不是如此,實際上訪問特定型別的變數只能在特定的位址訪問,這就需要各個變數在空間上按一定的規則排列,而不是...