位元組對齊詳解 C C 版本

2021-10-03 17:34:24 字數 1870 閱讀 6653

計算機中記憶體都是按位元組劃分的,位元組對齊就讓各類資料在按照特定的規則在記憶體中排列。如果乙個資料在記憶體中的位置剛好是他自身長度的整數倍,則為位元組對齊。

為了可以解決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.什麼是資料...