字節對齊

一、原則:
1.結構體內成員按自身按自身長度自對齊。
自身長度,如char=1,short=2,int=4,double=8,。所謂自對齊,指的是該成員的起始位置的內存地址必須是它自身長度的整數倍。如int只能以0,4,8這類的地址開始
2.結構體的總大小爲結構體的有效對齊值的整數倍
結構體的有效對齊值的確定:
1)當未明確指定時,以結構體中最長的成員的長度爲其有效值
2)當用#pragma pack(n)指定時,以n和結構體中最長的成員的長度中較小者爲其值。數據成員、結構體和類的有效對齊值:自身對齊值和指定對齊值中小的那個值。影響各成員偏移與總大小
3) attribute((aligned (n))),讓所作用的結構成員對齊在n字節自然邊界上。如果結構中有成員的長度大於n,則按照最大成員的長度來對齊。告訴編譯器一個結構體或者類或者聯合或者一個類型的變量(對象)分配地址空間時的地址對齊方式。也就是所,如 果將attribute((aligned(m)))作用於一個類型,那麼該類型的變量在分配地址空間時,其存放的地址一定按照m字節對齊(m必 須是2的冪次方)。並且其佔用的空間,即大小,也是m的整數倍,以保證在申請連續存儲空間的時候,每一個元素的地址也是按照m字節對齊。 影響整個結構的大小
attribute__ ((packed)),取消結構在編譯過程中的優化對齊,按照實際佔用字節數進行對齊。

二、正確處理字節對齊
   對於標準數據類型,它的地址只要是它的長度的整數倍就行了,而非標準數據類型按下面的原則對齊:
  數組 :按照基本數據類型對齊,第一個對齊了後面的自然也就對齊了。
  聯合 :按其包含的長度最大的數據類型對齊。
  結構體: 結構體中每個數據類型都要對齊。

ps:Vc,Vs等編譯器默認是#pragma pack(8),所以測試我們的規則會正常;注意gcc默認是#pragma pack(4),並且gcc只支持1,2,4對齊。套用三原則裏計算的對齊值是不能大於#pragma pack指定的n值

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