結構體內存對齊與位段

2021-10-22 02:09:34 字數 1650 閱讀 6847

二、位段

總結:

編譯器在計算結構體大小時,發生記憶體對齊

如:

struct s

;int

main()

問:程式的結果是多少?

char 乙個位元組;int 4個位元組

1+4=5 ?

答案是 8。

a. 第乙個成員偏移量為0。

b. 其他成員要在(偏移)對齊數的整數倍。

對齊數:編譯器預設對齊數與成員變數大小中的較小值

c. 結構體的總大小是成員中最大對齊數的整數倍。

d. 若有結構體巢狀,內結構體對齊自己的最大對齊數整數倍偏移量,外結構體整體大小是所有最大對齊數的整數倍(含內結構體成員的對齊數)

舉例說明更形象化:如

struct s

;int

main()

第乙個成員char 與結構體的偏移量為0,即佔據了第乙個位元組。

第二個成員int 大小是4位元組,vs平台下預設對齊數是8 ,取較小值 4 作為此成員的對齊數,->即變數 i 要在偏移為4的整數倍位址處開始儲存 往後存4個位元組:記憶體圖:

α. 平台原因:並非所有硬體平台都能訪問任意位址上的任意資料;某些硬體平台只能在特定位址上取值特定型別的資料。

β. 效能原因:資料結構應該盡可能在自然邊界上對齊,原因在於,訪問未對齊記憶體時,某些資料需要處理器訪問兩次才能得到完整資料,而對齊的記憶體僅需一次。

記憶體對齊 - -> 空間換時間。

a. 預編譯命令:#pragma pack(num)

修改編譯器預設對齊數為num個位元組

b. pack不帶引數,則恢復平台預設對齊數

#pragma pack(4) /將預設對齊數修改為4位元組

#pragma pack() /恢復預設對齊數為平台預設對齊數

位段的宣告與結構體類似

語法為:

struct a
α. 位段成員必須是int、unsigned int、char。

β. 位段成員後有乙個冒號和乙個數字。數字表示分配幾個bit位

在一定程度上節省空間

a. 在空間上以4位元組(int)或1位元組(char)方式來開闢。

b. 前乙個空間剩餘的bit位不夠時,直接浪費,使用新開闢空間的bit位。

c. 乙個位元組內部從低位向高位使用。

c語言標準並未規定上乙個空間沒用的bit位能否下乙個空間繼續使用;因此各個編譯器都有自己的實現。

位段最大的問題是跨平台的問題:

a. int位段不確定有無符號。

b. 位段中最大位數不確定.

c. 位段的成員在記憶體中分配方式不確定.

d. 當乙個結構含兩個位段,第二個位段大於第乙個位段餘留的空間時,餘留空間是舍是用不確定。

在編寫程式時,考慮到結構體存在記憶體對齊,可以將結構體中的成員變數合理安排位置,使程式所需記憶體空間得到有效利用。

結構體內存對齊,位段,列舉 聯合

結構體內存對齊規則 1.第乙個成員在與結構體變數偏移量為0的位址處2.其他成員變數要對齊到對齊數的整數倍的位址處。對齊數 編譯器預設的乙個對齊數與該成員大小的 較小值vs中預設的值為8,linux中的預設值為43.結構體總大小為最大對齊數 每乙個成員變數都有乙個對齊數 的整數倍4.如果巢狀了結構體的...

結構體內存對齊

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

結構體內存對齊

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