關於位元組對齊的看法

2022-09-13 02:12:10 字數 1250 閱讀 1103

由於cpu的讀取記憶體是以字長為單位的,而記憶體編址是一位元組為單位的,比如乙個32位機器,其讀取記憶體一次是4個位元組,而並不是乙個位元組為單位進行讀取。因為這個原因,期望編譯器變數在編址時要有所調整,以滿足最少次數讀取原則。

原始型別:

對於長度為乙個位元組的變數,無論其存放的位置如何都可以一次讀取記憶體來獲得其值,比如char a ,放在1,2,3,4,都是通過讀取1開始的這個字長塊記憶體,再根據位元組位址來獲取變數a的值,若放在2上,讀取第二個位元組開的長度為1的記憶體塊。

同樣道理,對於長度為兩個位元組的變數,那麼只要其存放開始位址是偶數,就能通過一次讀取記憶體來獲取。對於長度是4的變數,就必須儲存在以4的倍數為開始位址的記憶體塊,若不是,則需要cpu進行兩次讀取,然後再拼湊一次。

但是,對於長度超過4的型別,比如long long型別,其長度為8,我們可以發現,只要起始位置位址數值時4的倍數同樣能滿足要求。即 存放起始位置 % 型別長度 == 0 || 存放起始位置 % 4 == 0 。

我們發現沒,所有原始型別都是2的n次方, 如:1,2,4,8,16......同時編譯器對所有變數(包括結構型別變數)編址都是字長(4)的n倍。

結構型別:

結構型別需要看他位元組對齊長度和機器字長。

筆者vc預設對齊長度是4,32為機器,這意思是重開始位置開始以4為單位劃分塊,再加入成員變數,能夠容下就放入,不能容下就放入下乙個塊,對於型別長度超過分塊長的,就增加塊來放入。在結構的末尾,需要補全,使總長度為4n。

比如,char後跟乙個short,那麼能夠容下,這兩個成員將在乙個長度為4的塊中,要是shrot後再有乙個char,同樣能夠容下,一起放在這個塊中。要是short後跟乙個int,容不下,所有從下乙個塊開始放int,要是shourt後更乙個double,容不下,放入下乙個塊,但長度超過4,用兩個塊來存放。若是長度為6,那麼這後面還可以加入兩個char哦。

若對齊長度為2,按2來進行填充和補全。

當對齊長度超過機器字長,那麼按機器字長來進行進行對齊。比如若設對齊長度為8,那麼還是進行著以4為對齊長度的對齊。

通過#pragma pack(n) 和 #pragma pack(pop),來調整對齊長度,一般只需要改為1。當在網路上傳輸時,不同的機器的預設對齊方式可能不同,接收的buff的解析情況就會有差異。

struct

t

假設接收乙個物件t1的buff,指標p指向buff,若傳送接收兩方都採用同樣的對齊!用p->b來獲取不會出錯,要是發來這個buff的機器使用的長度為1的對齊,而本機用4,將會出錯。

後記:ok!總算完全理解了!

關於位元組對齊

用乙個例子簡單說明一下 v6環境 輸出結果 char 1 long 4 s1 8 s2 16 結果分析 棧由高向低增長,小端位元組序 addr s1.l 0x12ff7c addr s1.s 0x12ff78 addr s1 0x12ff78 addr s2.l 0x12ff74 addr s2.t...

關於位元組對齊

位元組 byte 是計算機資訊技術用於計量儲存容量和傳輸容量的一種計量單位,乙個位元組等於8位 二進位制數 在utf 8編碼中,乙個英文 字元等於乙個位元組。位元組按照一定規則在空間上排列就是位元組對齊。需要位元組對齊的根本原因在於cpu訪問資料的效率問題。假設上面整型變數的位址不是自然對齊,比如為...

關於位元組對齊的總結

1 使用預設的位元組對齊方式。規則1 各成員變數存放的起始位址相對於結構的起始位址的偏移量必須為該變數的型別所占用的位元組數的倍數。注 下面列出常用型別的對齊方式 vc6.0,32位系統 型別 對齊方式 變數存放的起始位址相對於結構的起始位址的偏移量 char 偏移量必須為sizeof char 即...