C語言結構體內存對齊

2021-07-06 09:58:45 字數 1577 閱讀 6752

1.效能原因:為了提高cup的效率訪問記憶體的速度,若是訪問未對齊的記憶體,處理器需要作兩次訪問;而訪問對齊的記憶體,則只需要一次訪問。

2.編譯器相關:有的編譯器已經優化了記憶體對齊,所以記憶體對齊依賴於編譯器。

參考 結構體對齊問題

說實話,規則看起來不太好理解,直接模仿下面步驟即可

以32位機器為例,工具為vs2008

型別所佔位元組

char

1bool

1short

2int

4long

4float

4double8指標

4 示例

struct person

;

步驟:

1.找出person中位元組數最長的成員b和f,長度為 n = 8;

2.從第乙個成員 a 開始計算,將 a 擺在 p = 0x00000 的位置。

3.計算第二個成員 b ,此時 b 的長度為 l = 8 ,其擺放的起始位址 p 需要滿足 p % l = 0 的條件。因此需要在之前填充7個位元組,則 p = 0x00008,其填充0x00008 - 0x00015共八個位元組。

4.計算第三個成員 c ,c 的長度為 l = 4 , 其擺放的起始位址 p = 0x00016, 滿足 p % l = 0,因此不需要在之前填充位元組,其填充0x00016 - 0x00019共四個位元組。

5.下面依次類推。

6.最後計算g,填充乙個位元組0x00040。

7.0x00000 - 0x00040共 41 個位元組,總位元組數sum必須滿足 sum % n = 0; n 數值看步驟1,所以最後還需要填充7個位元組,則 sum = 48;

**示例:

成員型別

所佔位元組

填充位元組數

儲存位址

achar80

0x00000

bdouble17

0x00008 - 0x00015

cint40

0x00016 - 0x00019

dint40

0x00020 - 0x00023

echar10

0x00024

fdouble87

0x00032 - 0x00039

gchar10

0x00040

長度sum = 41,成員變數最長型別所佔位元組數 n = 8,為滿足 sum % n = 0,需填充7個位元組,sum = 48;

順序1

struct person2

;

將 a 和 b 的順序調換,算出來的長度為 40,

順序2

struct person3

;

此時的長度為 32.

由於排列順序不一樣,person3 所佔的空間只有person的 67%,若是使用person結構體儲存資料量有乙個gb,那麼使用person3來儲存,只需要686mb,因此可以從記憶體對齊的角度來優化**,節省空間。

此段示例屬於最簡單的那種,還有更複雜的包含陣列的,還待研究。。。

C語言結構體內存對齊

記憶體中存放資料的時候要有一定的規則,這麼做得根本原因是要減少cpu訪問記憶體的次數。舉個例子,int型別為4個位元組,存放int型別的記憶體的起始位址就是4的倍數,這樣cpu訪問一次記憶體就能夠取到資料 跟cpu訪問記憶體的機制有關,加上cache的對映,一般cpu一次訪問64位元組的資料,也有1...

C語言 結構體內存對齊

1 平台原因 不是所有硬體平台都能夠訪問任意位址上的任意資料的,某些硬體平台只能在某些位址處取某些特定型別的資料,否則丟擲硬體異常。2 效能原因 主要原因 資料結構 尤其是棧 應該盡可能地在自然邊界上對齊。原因在於,為了訪問未對齊的記憶體,處理器需要作兩次記憶體訪問 而對齊的記憶體訪問僅需要一次訪問...

C語言結構體內存對齊

問題 求32bit環境下以下結構體所佔的位元組數 在32bit環境中,該結構體所佔的位元組數為16。先記住關於結構體內存對齊的三條原則 1 結構體變數的起始位址能夠被其最寬的成員大小整除。2 結構體每個成員相對於起始位址的偏移能夠被其自身大小整除,如果不能則在前乙個成員後面補充位元組。3 結構體總體...