C語言結構體內存對齊

2021-10-25 03:58:46 字數 1775 閱讀 1856

問題:求32bit環境下以下結構體所佔的位元組數

在32bit環境中,該結構體所佔的位元組數為16。

先記住關於結構體內存對齊的三條原則:

(1)結構體變數的起始位址能夠被其最寬的成員大小整除。

(2)結構體每個成員相對於起始位址的偏移能夠被其自身大小整除,如果不能則在前乙個成員後面補充位元組

(3)結構體總體大小能夠被最寬的成員的大小整除,如不能則在後面補充位元組

分析這個問題我們就不考慮編譯器可以指定對齊大小的情況了。在32bit環境中,一般預設的對齊大小是4。

下面我們根據這三條原則來分析,並得出如下示意圖:

結構體變數test_s的起始位址為0x0028ff30,能夠被其最寬的成員(int型別的d成員,佔4個位元組)整除,符合第(1)條原則。

a成員的位址即為結構體變數的起始位址0x0028ff30,排在a後面的是short型別(兩個位元組)的b成員。

根據第(2)條規則,顯然b的位址不能從0x0028ff31開始,則編譯器會在b成員的前乙個成員(a成員)後邊補1個空白位元組,即b的的位址為從0x0028ff32,符合規則(2)。

b成員佔兩個位元組,兩個位元組之後的位址為0x0028ff34,而c成員為char型別(1位元組),則根據規則(2),c成員會存放至位址0x0028ff34處。

c成員佔1個位元組,1個位元組之後的位址為0x0028ff35,排在c後面的是int型別(4個位元組)的d成員,顯然不能滿足規則(2)。

編譯器會在d成員的前乙個成員(c成員)後面進行位元組填充,這裡必須填充3個位元組才能符合規則(2),此時d會存放至位址0x0028ff38處。

d成員佔4個位元組,4個位元組之後的位址為0x0028ff3c。根據規則(2),e成員可從該位址開始存放。

此時a+空白位元組+b+c+空白位元組+d+e所佔的位元組總數為13個位元組,而結構體最寬的成員(int型別的d成員)所佔位元組數為4位元組。

顯然不能滿足規則(3),編譯器會在e成員後面填充3個位元組。即整個結構體變數test_s所佔的總位元組數為16位元組。

(1)調整結構體成員的位置

從上面的分析中我們知道編譯器會根據我們結構體成員的排列來進行空白位元組填充以達到對齊的效果。

那麼我們自己進行手動對齊一些成員,那就可以節省一些空間了。比如把上面的我們的test_struct結構體成員的順序改為:

typedef struct test_struct

test_struct;

則結構體變數test_s所佔的位元組數變為12位元組,即:

即比原來的16字節省下了4個位元組。

C語言結構體內存對齊

1.效能原因 為了提高cup的效率訪問記憶體的速度,若是訪問未對齊的記憶體,處理器需要作兩次訪問 而訪問對齊的記憶體,則只需要一次訪問。2.編譯器相關 有的編譯器已經優化了記憶體對齊,所以記憶體對齊依賴於編譯器。參考 結構體對齊問題 說實話,規則看起來不太好理解,直接模仿下面步驟即可 以32位機器為...

C語言結構體內存對齊

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

C語言 結構體內存對齊

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