關於C語言中結構體 聯合的記憶體對齊

2021-09-24 20:45:18 字數 1955 閱讀 6831

為什麼存在記憶體對齊?

1、平台原因(移植原因):不是所有的硬體平台都能訪問任意位址上的任意資料的;某些硬體平台只能在某些位址處取某些特定型別的資料,否則丟擲硬體異常。

2、效能原因:資料結構(尤其是棧)應該盡可能地在自然邊界上對齊。原因在於,為了訪問未對齊的記憶體,處理器需要作兩次記憶體訪問;而對齊的記憶體訪問僅需要一次訪問。

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

1、第乙個成員變數在與結構體變數偏移量為0的位址處。通俗來說,就是結構體中的第乙個成員變數不用考慮對齊。

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

3、結構體總大小為最大對齊數(每個成員變數都有乙個對齊數)的整數倍。如果不是整數倍,說明沒有對齊,需要將總大小擴充套件至能整除最大對齊數的位置。

4、如果巢狀了結構體的情況,巢狀的結構體對齊到自己的最大對齊數的整數倍處,結構體的整體大小就是所有最大對齊數(含巢狀結構體的對齊數)的整數倍。(選擇結構體和巢狀的結構體中的最大對齊數里最大的那個值)。

補充說明:

第乙個元素不用對齊,並不代表沒有對齊數,而是不需要。

對齊數=指定的乙個對齊數與該成員大小的較小值。

預設情況下,對齊數為自身的大小。

對齊:其他成員在放入結構體時,其起始偏移量能整除自身對齊數稱為對齊。

指定乙個對齊數:

#pragma pack(1) 只能設1 2 4 8 16 32……2^n。

每個變數對齊數和指定對齊數比較,選擇較小的對齊數,作為該變數的對齊數。

結構體大小測試:

#include #includestruct s1

;struct s2

;struct s3

;struct s4

;int main()

執行結果:

練習:struct b

;struct a

;解答:

對於結構體b的大小,起始偏移量為0,a的大小為1,故自身對齊數為1可以整除。

b的起始偏移量為1,b的對齊數為4,1不能整除4,故需要3個位元組的空間使其對齊。

c的起始偏移量為(1+3+4)8,對齊數為2,8能整除2,故直接加2。最後由規則3,結構體總大小為最大對齊數的整數倍,結構體中b的最大對齊數為4,故最後對齊時再加2,即8+2+2=12,所以結構體b的大小為12。

對於結構體a的大小,結構體a中巢狀結構體b,由規則4:如果巢狀了結構體(b)的情況,巢狀的結構體(b)對齊到自己的最大對齊數的整數倍處,結構體(a)的整體大小就是所有最大對齊數(含巢狀結構體的對齊數)的整數倍。結構體a的大小:1+3+4+3+1+4+12+1+12+3=44。

union 共用體名;

結構體和共用體的區別在於:結構體的各個成員會占用不同的記憶體,互相之間沒有影響;而共用體的所有成員占用同一段記憶體,修改乙個成員會影響其餘所有成員。

結構體占用的記憶體大於等於所有成員占用的記憶體的總和(成員之間可能會存在縫隙),所以聯合占用的記憶體大小也要考慮自身記憶體對齊。共用體使用了記憶體覆蓋技術,同一時刻只能儲存乙個成員的值,如果對新的成員賦值,就會把原來成員的值覆蓋掉。

聯合的占用記憶體的大小計算:只需要整除最大對齊數即可,最後類似根據結構體規則3:結構體總大小為最大對齊數(每個成員變數都有乙個對齊數)的整數倍。如果不是整數倍,說明沒有對齊,需要將總大小擴充套件至能整除最大對齊數的位置。即可算出聯合的大小。

測試**如下:

#include #includeunion un1 

;union un2

;int main()

測試結果:

C語言中關於結構體的記憶體對齊

以前沒太總結,今天看飛卡的書偶然看到的乙個關於嵌入式c結構體的知識,趕緊來記錄下,方便以後忘記了再次查閱。1 自然對齊 兩個原則 1 各個型別偏移量必須是自身所佔位元組數的整數倍。譬如,int佔4位元組,它的偏移量也必須是4的倍數 2 總的大小必須為該結構體中最大記憶體的整數倍,不夠需要補充。對了,...

關於C語言中的結構體對齊

關於c語言中的結構體對齊 1 什麼是位元組對齊 乙個變數占用 n 個位元組,則該變數的起始位址必須能夠被 n 整除,即 存放起始位址 n 0,對於結構體而言,這個 n 取其成員種的資料型別佔空間的值最大的那個。2 為什麼要位元組對齊 記憶體空間是按照位元組來劃分的,從理論上說對記憶體空間的訪問可以從...

C語言中結構體占用記憶體問題

之前對結構體占用記憶體一直很混亂,到底是按照哪個變數型別計算記憶體?還是怎麼計算?下面先看乙個例子 struct str1 str1這個結構體占用的記憶體是多少呢?如果用變數型別直接想加,得到的結果是17,但顯然不是這樣的。這個程式執行的正確結果是24.為什麼呢?因為為了cpu能夠快速訪問,提高訪問...