C 位元組對齊

2021-08-18 03:15:20 字數 2836 閱讀 9678

這篇部落格主要介紹c++位元組對齊的方式

什麼是位元組對齊

現代計算機中記憶體空間都是按照

byte

劃分的,從理論上講似乎對任何型別的變數的訪問可以從任何位址開始,但實際情況是在訪問特定型別變數的時候經常在特 定的

記憶體位址

訪問,這就需要各種型別資料按照一定的規則在空間上排列,而不是順序的乙個接乙個的排放,這就是對齊。

為什麼要位元組對齊

各個硬體平台對儲存空間的處理上有很大的不同。一些平台對某些特定型別的資料只能從某些特定位址開始訪問。比如有些架構的cpu在訪問 乙個沒有進行對齊的變數的時候會發生錯誤,那麼在這種架構下程式設計必須保證位元組對齊.其他平台可能沒有這種情況,但是最常見的是如果不按照適合其平台要求對 資料存放進行對齊,會在訪問效率上帶來損失。比如有些平台每次讀都是從偶位址開始,如果乙個int型(假設為32位系統)如果存放在偶位址開始的地方,那麼乙個讀週期就可以讀出這32bit,而如果存放在奇位址開始的地方,就需要2個讀週期,並對兩次讀出的結果的高低位元組進行拼湊才能得到該32bit資料。

位元組對齊的準則

其實位元組對齊的細節和具體編譯器

1) 結構體

變數的首位址能夠被其最寬基本型別成員的大小所整除;

2) 結構體每個成員相對於結構體首位址的偏移量

都是成員大小的整數倍,如有需要編譯器會在成員之間加上填充位元組;例如上面第二個結構體變數的位址空間

。3) 結構體的總大小為結構體最寬基本型別成員大小的整數倍,如有需要編譯器會在最末乙個成員之後加上填充位元組。

位元組對齊的概念與規則

1.資料型別自身的對齊值:

對於char型資料,其自身對齊值為1,對於short型為2,對於int,float型別,其自身對齊值為4,對於double型,其自身對齊值為8,單位位元組。

2.結構體或者類的自身對齊值:其成員中自身對齊值最大的那個值。

3.指定對齊值:#pragma pack (value)時的指定對齊值value。

4.資料成員、結構體和類的有效對齊值:自身對齊值和指定對齊值中小的那個值。

有效對齊值n是最終用來決定資料存放位址方式的值,最重要。有效對齊n,就是表示「對齊在n上」,也就是說該資料的"存放起始位址%n=0".而資料結構中的資料變數都是按定義的先後順序來排放的。第乙個資料變數的起始位址就是資料結構的起始位址。結構體的成員變數要對齊排放,結構體本身也要根據自身的有效對齊值圓整。

栗子1、結構體

變數的首位址能夠被其最寬基本型別成員的大小所整除

struct a

;

a* a=new a();
在我的機器上,a的位址上0x26e1200,可以整除double的大小8,符合準則1、結構體

變數的首位址能夠被其最寬基本型別成員的大小所整除

栗子2、怎麼計算只含基本型別成員的結構體的大小

struct a

;

如果不考慮位元組對齊,那麼顯然結構體a的大小為4+8+1=13。如果考慮位元組對齊,我們只需要記住兩點,第

一、每個成員在結構體裡的偏移都是其自身大小的整數倍,第

二、結構體的總大小為最寬基本型別成員大小的整數倍

對於a,其大小為4,那麼可以放在偏移為0的地方,0是4的0倍,對於b,其大小為8,可以放在偏移為8的地方,8是8的1倍,對於c可以放在偏移為16的地方,9是1的9倍,現在,結構體的大小為17,然而最寬基本型別成員是b,其大小是8,比17大的8的倍數的數字是24,所以整個結構體的大小為24

上面的栗子的布局情況像這樣,灰色代表編譯器為了位元組對齊而填充的位元組

栗子3、怎麼計算含結構體的結構體的大小

struct a

;struct b

;

對於含有結構體的結構體,麻煩在於我們不知道結構體怎麼算對齊值,因為偏移是根據大小來確定的,結構體的大小是根據其自己最大基本型別成員的大小來決定的。當然,我說的不是結構體真正的大小,而是結構體計算大小,也就是上面說的對齊值。基本型別成員的對齊值就是自身大小,結構體的對齊值是自己最大基本型別成員的大小。所以在這裡,a的對齊值是8,所以它應該放在偏移為0的地方,0是8的0倍,結構體b應該放在偏移為8的地方,8是8的1倍,c應該放在32的地方,32是1的32倍,現在,結構體的大小為33,然而最寬的成員大小既是a,也是結構體b,大小都是8,所以比33大的8的倍數的數字是40,整個結構體的大小為40

上面的栗子的布局情況像這樣,灰色代表編譯器為了位元組對齊而填充的位元組

栗子4、怎麼計算含有指定對齊值的結構體的大小

我們可以通過#pragma pack (value)來指定我們想要的對齊值,結構體真正的對齊值是我們指定對齊值和結構體本身對齊值較小的乙個

#pragma pack(4)
struct a

;

我們已經在栗子1中見過這個結構體,這個結構體的對齊值是其自身最大的基本型別成員,也就是b,大小為8,可我們指定的對齊的大小為4,所以這個結構的有效對齊值為4

a應該放在偏移為0的地方,0是4的0倍,b應該放在偏移為4的地方,8是4的2倍,c應該放在偏移為12的地方,12是1的12倍,現在,結構體的大小為13,比13大的4的倍數為16,所以整個結構體的大小為16

上面的栗子的布局情況像這樣,灰色代表編譯器為了位元組對齊而填充的位元組

mysql位元組對齊 C 位元組對齊彙總

一 什麼是位元組對齊 現代計算機中記憶體空間都是按照byte劃分的,從理論上講似乎對任何型別的變數的訪問可以從任何位址開始,但實際情況是在訪問特定型別變數的時候經常在特定的記憶體位址訪問,這就需要各種型別資料按照一定的規則在空間上排列,而不是順序的乙個接乙個的排放,這就是對齊。二 位元組對齊的原因和...

c 位元組對齊

1.虛函式 如果 classa 有虛函式,編譯器會給每個 classa 物件新增乙個隱藏成員,該隱藏成員儲存了乙個指向虛函式表的指標.所以 sizeof classa 如果比你預想的多了 4 位,不要驚奇,因為多了乙個 size 指標 但是這個隱藏指標是先算還是後算呢?class a int a c...

c 位元組對齊

在 c 中位元組對齊主要存在符合型別中 union struct 和class中 先介紹四個概念 1 資料型別自身的對齊值 基本資料型別的自身對齊值,等於sizeof 基本資料型別 2 指定對齊值 pragma pack value 時的指定對齊值value。3 結構體或者類的自身對齊值 其成員中自...