計算機中記憶體都是按位元組劃分的,位元組對齊就讓各類資料在按照特定的規則在記憶體中排列。如果乙個資料在記憶體中的位置剛好是他自身長度的整數倍,則為位元組對齊。
為了可以解決cpu讀寫資料效率的問題
因為每個平台cpu所讀取的位元組數是不同的,例如乙個平台每次總是讀取4個位元組,又有如下結構體:
struct test
;
⚪如果不進行記憶體對齊(不對齊採用1位元組對齊),該結構體在記憶體中排列方式如下圖所示(int 4位元組,short 2位元組,double 8位元組):
這時候cpu取資料可能要執行兩次或多次記憶體訪問,降低效率。
⚪如果進行記憶體對齊(這裡採用8位元組對齊),該結構體在記憶體中排列方式如下圖所示:
這裡我們就發現讀取資料可以很方便的每次從4的倍數位元組開始的地方進行讀取,提公升了讀取效率。
為了解決跨平台資料資料讀取問題
有的人開發時可能會遇到,明明在自己機器上可以正常執行讀取資料,但到了別的平台無法讀取各種奇怪的問題。這裡就很有可能不同平台的cpu資料讀取方式不同,又加之沒有進行特定的位元組對齊處理所導致的。所以一般跨平台可以使用1位元組對齊,節省空間,但是效率過低。
在c++中
主要通過 #pragma pack(n) 來實現
常用位元組對齊指令如下:
指令效果
#pragma pack (n)
作用:c編譯器將按照n個位元組對齊。
#pragma pack ()
作用:取消自定義位元組對齊方式。
#pragma pack (push,n)
作用:是指把原來對齊方式設定壓棧,並設新的對齊方式,n不填就是不設定新的對齊方式
#pragma pack(pop)
作用:恢復對齊狀態
還是上面的**,我們使用四位元組對齊:
#pragma pack(4)
struct test
;
執行結果為16。畫圖表示:
在c#中主要通過 [structlayout(layoutkind.sequential,charset =charset.ansi,pack =8)] 來實現。
還是上面的**,在c#中,也採用4位元組對齊
[
structlayout
(layoutkind.sequential,charset =charset.ansi,pack =4)
]struct test
static
void
main
(string
args)
和上面c++執行結果一樣,都為16。
講完了嗎,不還沒有,神奇的問題出現了。
還是剛才的**,順序稍微換一下,分別採用4位元組和8位元組對齊,可以猜猜看各自是多少。
//#pragma pack(4)
#pragma pack(8)
struct test
;
結果為乙個16位元組(4位元組對齊),乙個24位元組(8位元組對齊)。
是的,結果體內部欄位的排列順序會影響位元組對齊所佔空間大小。(當然如果都用1位元組對齊那沒有什麼關係,但效率可想而知~)。
所以得出結論,結構體內部字段順序,位元組數越小的最好放在最上邊
C C 位元組對齊詳解
一.什麼是位元組對齊,為什麼要對齊?現代計算機中記憶體空間都是按照byte劃分的,從理論上講似乎對任何型別的變數的訪問可以從任何位址開始,但實際情況是在訪問特定型別變數的時候經常在特 定的記憶體位址訪問,這就需要各種型別資料按照一定的規則在空間上排列,而不是順序的乙個接乙個的排放,這就是對齊。對齊的...
C C 位元組對齊詳解
一.什麼是位元組對齊,為什麼要對齊?現代計算機中記憶體空間都是按照byte劃分的,從理論上講似乎對任何型別的變數的訪問可以從任何位址開始,但實際情況是在訪問特定型別變數的時候經常在特 定的記憶體位址訪問,這就需要各種型別資料按照一定的規則在空間上排列,而不是順序的乙個接乙個的排放,這就是對齊。對齊的...
C C 記憶體位元組對齊詳解
from 例1 include stdafx.h include using namespace std struct a struct b 換乙個順序 int main 其輸出結果為 24 換行 16 不同樣結構體包含相同的元素型別,為什麼得到的長度不相同呢?這就 牽扯到 資料對齊 1.什麼是資料...