您好,登錄后才能下訂單哦!
這篇文章主要介紹“需要字節對齊的原因有哪些”,在日常操作中,相信很多人在需要字節對齊的原因有哪些問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”需要字節對齊的原因有哪些”的疑惑有所幫助!接下來,請跟著小編一起來學習吧!
字節對齊
現代計算的內存是以字節來劃分的,理論上可以計算機可以從任意地址開始訪問任意的變量。但實際中,計算機在訪問特定類型變量時,經常從特定的內存地址訪問,這就需要各種類型數據按照一定的規則在空間上排列,這個規則,就叫做內存對齊。
需要字節對齊的原因
計算機是通過總線來訪問內存的,而總線的寬度一般是32位或者64位,假設是32位總線,每個總線周期,計算機都會從偶地址開始訪問32位內存數據。如果一個32位的數據沒有存放在4字節整除的內存地址處,那么處理器就需要2個總線周期才能對其進行訪問,自然會降低訪問的效率。所以,為了使CPU能夠對數據進行快速訪問,數據的起始地址應具有“對齊”特性。比如4字節數據的起始地址應位于4字節邊界上,即起始地址能夠被4整除。
字節對齊的分類
字節對齊分為兩種:
結構體對齊,結構體對齊是字節對齊的主要對象。
棧對齊,函數中的局部變量也需要對齊,一般按照4字節對齊。
結構體字節對齊
編譯器為結構體的每個成員按照其自然邊界分配空間。
各成員按照他們被聲明的順序在內存中順序的存儲。
第一個成員的地址和整個結構體的地址相同。
結構體對齊的4個基本概念
1) 數據類型自身的對齊值:char型數據自身對齊值為1字節,short型數據為2字節,int/float型為4字節,double型為8字節。 2) 結構體或類的自身對齊值:其成員中自身對齊值最大的那個值。 3) 指定對齊值:#pragma pack (value)時的指定對齊值value。 4) 數據成員、結構體和類的有效對齊值:自身對齊值和指定對齊值中較小者,即有效對齊值=min{自身對齊值,當前指定的pack值}。
期中,有效對其值N,是最終用來決定數據存放地址方式的值。有效對其N表示“對齊在N上”,即該數據的“存放起始地址%N=0”。而數據結構中的數據變量都是按定義的先后順序存放。第一個數據變量的起始地址就是數據結構的起始地址。結構體的成員變量要對齊存放,結構體本身也要根據自身的有效對齊值圓整(即結構體成員變量占用總長度為結構體有效對齊值的整數倍,以便對結構體數據進行高效的訪問)。
結構體對齊的3個基本準則
1) 結構體變量的首地址能夠被其最寬基本類型成員的大小所整除; 2) 結構體每個成員相對結構體首地址的偏移量(offset)都是成員大小的整數倍,如有需要編譯器會在成員之間加上填充字節(internal adding); 3) 結構體的總大小為結構體最寬基本類型成員大小的整數倍,如有需要編譯器會在最末一個成員之后加上填充字節{trailing padding}。
第一條:編譯器在給結構體開辟空間時,首先找到結構體中最寬的基本數據類型,然后尋找內存地址能被該基本數據類型所整除的位置,作為結構體的首地址。將這個最寬的基本數據類型的大小作為上面介紹的對齊模數。
第二條:為結構體的一個成員開辟空間之前,編譯器首先檢查預開辟空間的首地址相對于結構體首地址的偏移是否是本成員大小的整數倍,若是,則存放本成員,反之,則在本成員和上一個成員之間填充一定的字節,以達到整數倍的要求,也就是將預開辟空間的首地址后移幾個字節。
第三條:結構體總大小是包括填充字節,最后一個成員滿足上面兩條以外,還必須滿足第三條,否則就必須在最后填充幾個字節以達到本條要求。
不同處理器間的數據通信
在不同編譯平臺或處理器上,字節對齊會造成消息結構長度的變化。
編譯器為了使字節對齊可能會對消息結構體進行填充,不同編譯平臺可能填充為不同的形式,大大增加處理器間數據通信的風險。
為了解決上述問題,可以按如下方案進行操作:
1)對于本地使用的數據結構,為提高內存訪問效率,采用四字節對齊方式; 同時為了減少內存的開銷,合理安排結構體成員的位置,減少四字節對齊導致的成員之間的空隙,降低內存開銷。 2)對于處理器之間的數據結構,需要保證消息長度不會因不同編譯平臺或處理器而導致消息結構體長度發生變化,使用一字節對齊方式對消息結構進行緊縮; 為保證處理器之間的消息數據結構的內存訪問效率,采用字節填充的方式自己對消息中成員進行四字節對齊。 3)數據結構的成員位置要兼顧成員之間的關系、數據訪問效率和空間利用率。 順序安排原則是:四字節的放在最前面,兩字節的緊接最后一個四字節成員,一字節緊接最后一個兩字節成員,填充字節放在最后。
默認的字節對齊方式
32位機一般默認4字節對齊(32位機機器字長4字節),
64位機一般默認8字節對齊(64位機機器字長8字節) 。
更改字節對齊的方式
使用偽指令#pragma pack(n):C編譯器將按照n個字節對齊;
使用偽指令#pragma pack(): 取消自定義字節對齊方式。
字節對齊的方式與sizeof的值
不同的字節對齊方式,可能影響sizeof的值,在使用sizeof的時候,要認證考慮當前字節對齊的長度。
在進行網絡通信的時候,往往需要傳輸一塊buffer,這個buffer的長度,一定要顯示指定,解析的時候也必須使用這個長度。
到此,關于“需要字節對齊的原因有哪些”的學習就結束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續學習更多相關知識,請繼續關注億速云網站,小編會繼續努力為大家帶來更多實用的文章!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。