结构体内存对齐详解
目錄
前言
代碼示例
結(jié)構(gòu)體內(nèi)存對齊規(guī)則
畫圖解題
為什么存在內(nèi)存對齊
如何設(shè)計結(jié)構(gòu)體
修改默認(rèn)對齊數(shù)
結(jié)語
前言
結(jié)構(gòu)體內(nèi)存對齊問題是結(jié)構(gòu)體中非常重要的知識點,本文此進(jìn)行詳細(xì)的總結(jié)。
代碼示例
以上代碼中,結(jié)構(gòu)體成員變量一樣,但是順序不一樣,導(dǎo)致兩個結(jié)構(gòu)體所占內(nèi)存大小不同,這是為什么呢?
結(jié)構(gòu)體內(nèi)存對齊規(guī)則
1.第一個成員在結(jié)構(gòu)體變量偏移量為0的地址處。
2.其他成員變量要對齊到某個數(shù)字(對齊數(shù))的整數(shù)倍的地址處。
對齊數(shù) = 編譯器默認(rèn)的對齊數(shù)與該成員大小的較小值。
3.結(jié)構(gòu)體總大小為最大對齊數(shù)的整數(shù)倍(每個成員變量都有一個對齊數(shù))。
4.如果嵌套了結(jié)構(gòu)體,嵌套的結(jié)構(gòu)體對齊到自己最大對齊數(shù)的整數(shù)倍處,結(jié)構(gòu)體的整體大小就是所有所有最大的對齊數(shù)的整數(shù)倍(包含嵌套結(jié)構(gòu)體的對齊數(shù))。
畫圖解題
這個規(guī)則有點抽象,接下來畫圖示例。
?
為什么存在內(nèi)存對齊
1.平臺原因
不是所有硬件可以訪問任意地址處上的任意數(shù)據(jù),某些平臺只能在某些地址處讀取特定類型數(shù)據(jù),否則會硬件異常。
2.性能原因
數(shù)據(jù)結(jié)構(gòu)(尤其是棧)應(yīng)該盡可能在自然邊界上對齊
原因在于,為了訪問未對齊的內(nèi)存,處理器需要作兩次內(nèi)存訪問;而對于對齊的內(nèi)存,處理器僅需要一次訪問。
如何設(shè)計結(jié)構(gòu)體
為了使結(jié)構(gòu)體占用的內(nèi)存小一點,我們應(yīng)該經(jīng)可能讓占用空間小的內(nèi)存集中在一起,如有兩個char、兩個int、兩個double類型的數(shù)據(jù),我們應(yīng)該以char char int int double double double這樣的順序排列結(jié)構(gòu)體成員變量,減少內(nèi)存的浪費。
修改默認(rèn)對齊數(shù)
我使用的是vs2019的編譯器,默認(rèn)的對齊數(shù)是8,如果結(jié)構(gòu)體在對齊方式不合適的時候,可以自己更改默認(rèn)對齊數(shù)。這時候需要在程序開頭使用 #pragma pack(設(shè)置的默認(rèn)對齊數(shù))。
結(jié)語
本文到此結(jié)束,希望讀者有所收獲,謝謝閱覽。
總結(jié)