C語言結構體儲存及對齊

2021-06-18 23:18:27 字數 1000 閱讀 6943

規則1:結構體的資料成員中,第乙個成員的offset為0;

規則2:結構體的資料成員中,每個成員的offset為本成員大小的整數倍;

規則3:若結構體a作為另乙個結構體b的資料成員,則結構體a作為乙個整體參與規則1和規則2;

規則4:結構體的總大小(sizeof)不是簡單的所有成員大小的總和,為該結構體內部最大成員資料型別的整數倍,單個成員大小不夠的參考規則2以最簡方式進行在尾部補齊。

step1:對結構體所有資料成員的大小進行排序

step2:參考規則4,先根據結構體中最大成員的大小,確定最初(也是最粗)的對齊邊界,並放置最大的結構體成員;

step3:參考step2,基於在結構體中定於的順序,相鄰插入其次大小的成員變數,並以上次放置設定對齊邊界進行對齊,然後更新本資料成員的對齊邊界為當前的對齊邊界;

step4:重複step3,直至放置完最後乙個元素;

step5:參考規則1,為放置好的元素從0開始設定offset。

在使用了#pragma pack(x)巨集配置之後,將修正基本規則中的規則4和規則2,結構體的各資料成員大小及總大小將以巨集配置引數x決定。

例如若使用了#pragma pack(2)則對齊的基準將是2,此時可以直接從結構體中的第乙個成員開始依次計算offset,只要保證各自的對齊滿足由巨集引數(在本例中為2)指定大小的整數倍即可。

大小端是資料元素內部組織資料的方式,不影響巨集觀的結構體的儲存劃分。

在嵌入式開發中,對記憶體的管理非常嚴格,大小端和結構體儲存的安排是個非常敏感的話題,並且不同裝置使用的標準在事實上存在差異並廣泛存在(例如廣泛使用的arm處理器使用的是小端對齊,而廣泛使用的網路資料流對資料的儲存則使用大端對齊)。實際上,在實際的開發中,尤其是面向資料流的處理時,這些就是必須要考慮的問題了。為了考慮程式和裝置的相容性,使用#pragma pack巨集配置命令依賴於編譯器,並不是乙個很好的選擇,建議將資料序列化成基本的位元組流,將結構體定義欄位的偏移量作為索引進行訪問,這樣可以避免在資料傳輸中的大小端轉換的問題。但在某些具體的應用中,使用專門的大小端轉換函式也是有必要的。

c語言 結構體對齊

1 編譯器是按照什麼樣的原則進行對齊的?a.資料型別自身的對齊值 對於char型資料,其自身對齊值為1,對於short型為2,對於int,float,double型別,其自身對齊值為4,單位位元組。b.結構體或者類的自身對齊值 其成員中自身對齊值最大的那個值。c.指定對齊值 pragma pack ...

C語言結構體對齊

解析c語言結構體對齊 記憶體對齊問題 c語言結構體對齊也是老生常談的話題了。基本上是面試題的必考題。內容雖然很基礎,但一不小心就會弄錯。寫出乙個struct,然後sizeof,你會不會經常對結果感到奇怪?sizeof的結果往往都比你宣告的變數總長度要大,這是怎麼回事呢?開始學的時候,也被此類問題困擾...

c語言結構體對齊

c語言結構體對齊也是老生常談的話題了。基本上是面試題的必考題。結構體到底怎樣對齊?下面總結了對齊原則,在沒有 pragma pack巨集的情況下 原則1 普通資料成員對齊規則 第乙個資料成員放在offset為0的地方,以後每個資料成員儲存的起始位置要從該成員大小的整數倍開始 比如int在32位機為 ...