struct結構體的記憶體對齊

2021-09-28 18:56:50 字數 2138 閱讀 7794

1、結構體中第乙個成員在 與結構體變數偏移量為0 的位置;

2、其他成員變數要對齊到某個數字(對齊數)的整數倍的位址處;

注意:(1)對齊數 = 編譯器預設的乙個對齊數 與 該成員所佔空間的位元組數 的較小值

(2)vs中預設的對其數是8,linux中的預設值為4。

3、成員對其後,結構體自身也要對齊。結構體的總大小為成員中最大的對齊數(每個成員變數都有乙個自己的對齊數)的整數倍;

4、如果結構體a中包含另一結構體b的變數,巢狀的結構體b對齊到 自己成員中的最大對齊數 的整數倍,結構體a的總大小就是成員中最大的對齊數(包含結構體b變數的對齊數,結構體b變數的對齊數就是結構體b的最大對齊數)的整數倍。

例如:

//在vs08下測試,使用vs預設的對齊數8。

struct a

c; char b;

};//a的總大小為32,先解決struct b,aa佔1位元組,bb占用8位元組,bb的對齊數通過「對齊規則2」計算為8,所以1 + 7 + 8,此時struct b整體也要對齊一下,而struct b的最大對齊數為8,所以最終struct b的大小為1 + 7 + 8 + 1 = 16位元組。

//a佔1位元組,c占用16位元組,但是c的對齊數是8,所以1 + 7 + 16,b佔1位元組,b的對齊數是1,所以1 + 7 + 16 + 1 = 25,此時struct a整體也要對齊一下,而struct a的最大對齊數為8,所以25 + 7 = 32。

#pragma pack(1/2/4/8/16)//修改編譯器的預設對齊數

//如果引數不是1/2/4/8/16,在vs08下:warning c4086: 雜注引數應為「1」、「2」、「4」、「8」或者「16」

#pragma pack()//把修改後的對齊數再改回來

//在vs08下測試,使用vs預設的對齊數8。

struct a

; char b;

};//此時,struct a大小只有2位元組。

struct a

;//struct a的大小為21位元組

不是所有的硬體平台都能訪問任意位址上的任意資料的,某些硬體平台只能在某些位址處取某些特定型別的資料,否則丟擲硬體異常。

2、效能原因

資料結構(尤其是棧)應該盡可能地在自然邊界上對齊。

原因在於,為了訪問未對齊的記憶體,處理器需要做兩次記憶體訪問,而對齊的記憶體僅需要一次訪問。

進一步解釋一下

cpu在取資料的時候一般都是4位元組或8位元組的取(32位cpu指的是cpu一次能處理的最大位數是32,並且它的記憶體定址能力是32位,此時指標變數的大小為4位元組。),以下圖為例

沒有記憶體對齊的話,取出來的資料就是乙個char和3/4個int,不是乙個完整的int,為了取出乙個完整的int,還得再取一次。

總體來說,結構體的記憶體對齊是拿空間換取時間的做法。

那在設計結構體的時候,我們既要滿足對齊,又要節省空間,如何做到?

讓占用空間小的成員盡量集中在一起

struct s1

;//改為

struct s2

;

1、聯合體的大小至少是最大成員的大小;

2、當最大成員大小不是最大對齊數的整數倍的時候,就要對齊到最大對齊數的整數倍。

和struct類似,直接舉例:

//在vs08下測試

#pragma pack(4)

union a

;//大小是12,雖然聯合體中所有成員都在 與聯合體變數偏移量為0 的位置,但是聯合體a最終也要整體對齊一下,所以是12。

#pragma pack()

union b

;//大小是16

struct c

;//大小為24

結構體struct記憶體對齊

原因 結構體內存對齊是因為,對於計算機來說讀取4個位元組的記憶體空間比讀取1 2 3個位元組的要更高效。但是也根據編譯器而定,而且自己也可以改變對齊記憶體的大小用 預編譯命令 pragma pack n 規則 1.第乙個元素offset偏移到位址為0的記憶體上。2.之後的元素對齊到對齊數大小的整數倍...

結構體struct 的記憶體對齊問題(c語言)

對齊原因 1 為了避免移植後計算機讀取資料出錯 各個硬體平台對儲存空間的處理上有很大的不同,某些硬體平台只能在某些位址處去某些特定型別的資料,否則會出錯 2 為了提高計算機取數的效率 比如有些平台每次讀都是從偶位址開始,如果乙個int型 32位系統 如果放在偶數字址開始的地方,那麼一乙個讀週期就可以...

結構體struct的對齊問題

c語言結構體對齊也是老生常談的話題了。基本上是面試題的必考題。內容雖然很基礎,但一不小心就會弄錯。寫出乙個struct,然後sizeof,你會不會經常對結果感到奇怪?sizeof的結果往往都比你宣告的變數總長度要大,這是怎麼回事呢?開始學的時候,也被此類問題困擾很久。其實相關的文章很多,感覺說清楚的...