通過#pragma pack(n)改變c編譯器的位元組對齊方式
在c語言中,結構是一種復合資料型別,其構成元素既可以是基本資料型別(如int、long、float等)的變數,也可以是一些復合資料型別(如陣列、結構、聯合等)的資料單元。在結構中,編譯器為結構的每個成員按其自然對界(alignment)條件分配空間。各個成員按照它們被宣告的順序在記憶體中順序儲存,第乙個成員的位址和整個結構的位址相同。
例如,下面的結構各成員空間分配情況:
struct test
;結構的第乙個成員x1,其偏移位址為0,佔據了第1個位元組。第二個成員x2為short型別,其起始位址必須2位元組對界,因此,編譯器在x2和x1之間填充了乙個空位元組。結構的第三個成員x3和第四個成員x4恰好落在其自然對界位址上,在它們前面不需要額外的填充位元組。在test結構中,成員x3要求4位元組對界,是該結構所有成員中要求的最大對界單元,因而test結構的自然對界條件為4位元組,編譯器在成員x4後面填充了3個空位元組。整個結構所佔據空間為12位元組。
更改c編譯器的預設位元組對齊方式
在預設情況下,c編譯器為每乙個變數或是資料單元按其自然對界條件分配空間。一般地,可以通過下面的方法來改變預設的對界條件:
· 使用偽指令#pragma pack (n),c編譯器將按照n個位元組對齊。
· 使用偽指令#pragma pack (),取消自定義位元組對齊方式。
另外,還有如下的一種方式:
· __attribute((aligned (n))),讓所作用的結構成員對齊在n位元組自然邊界上。如果結構中有成員的長度大於n,則按照最大成員的長度來對齊。
· __attribute__ ((packed)),取消結構在編譯過程中的優化對齊,按照實際占用位元組數進行對齊。
以上的n = 1, 2, 4, 8, 16... 第一種方式較為常見。
應用例項
在網路協議程式設計中,經常會處理不同協議的資料報文。一種方法是通過指標偏移的方法來得到各種資訊,但這樣做不僅程式設計複雜,而且一旦協議有變化,程式修改起來也比較麻煩。在了解了編譯器對結構空間的分配原則之後,我們完全可以利用這一特性定義自己的協議結構,通過訪問結構的成員來獲取各種資訊。這樣做,不僅簡化了程式設計,而且即使協議發生變化,我們也只需修改協議結構的定義即可,其它程式無需修改,省時省力。下面以tcp協議首部為例,說明如何定義協議結構。其協議結構定義如下:
#pragma pack(1) // 按照1位元組方式進行對齊
struct tcpheader
; #pragma pack() // 取消1位元組對齊方式
0
給主人留下些什麼吧!~~
關於C編譯器裡位元組對齊的問題
宣告 只是為了方便個人學習用 首先是來自http blog.csdn.wenddy112 articles 300583.aspx 通過 pragma pack n 改變c編譯器的位元組對齊方式 上的乙個問題 對於下面的結構體 struct test 結構各成員空間分配情況是怎樣的?文章中解釋 結構...
C中位元組對齊問題
好多筆試中,會考結構體的sizeof是多少,這就涉及到了位元組對齊問題。vc或gcc編譯器,預設按4位元組對齊 什麼叫位元組對齊?就是資料在記憶體中存放的方式,它存放的位址需要是它長度的整數倍。比如單位元組放在什麼位址都可以,雙位元組資料只能存放在偶位址上,4位元組數只能存放在是4的倍數的位址上。注...
VC 中關於位元組對齊的問題
vc中下面幾個結構體大小分別是多少呢 struct mystruct struct mystruct pragma pack push 儲存對齊狀態 pragma pack 16 設定為16位元組對齊 struct test pragma pack pop 恢復對齊狀態 如果你的答案不是16,24和...