一篇文章帶你了解C語(yǔ)言內(nèi)存對(duì)齊
內(nèi)存對(duì)齊
先看如下代碼:
結(jié)構(gòu)體Test1占用了多少字節(jié)?如果事先不知道內(nèi)存對(duì)齊的話,答案肯定是:1個(gè)字節(jié)(char)+ 4個(gè)字節(jié)(int)+ 1個(gè)字節(jié)(char) = 6個(gè)字節(jié)。
事實(shí)上,Test1結(jié)構(gòu)體占用了12個(gè)字節(jié),從DEBUG模式下Watch1觀察:
OK,不就猜少了6個(gè)字節(jié)嗎?有什么影響嗎?先不說影響吧,咱們先來看看單片機(jī)內(nèi)存里的實(shí)際情況。從上圖看到,結(jié)構(gòu)體變量的首地址是0x200018F4,通過Keil的Memory1可以看到結(jié)構(gòu)體Text1在內(nèi)存的分布,如下圖所示。
將Test1的內(nèi)存分布提取出來,如下圖所示,因?yàn)閮?nèi)存對(duì)齊的原因,有6個(gè)字節(jié)被填充了。換句話說,這6個(gè)字節(jié)被浪費(fèi)了,無(wú)法被其他資源使用了(因?yàn)榫幾g器將這些內(nèi)存規(guī)劃給結(jié)構(gòu)體Test1了)。此時(shí),如果使用結(jié)構(gòu)體Text1在堆內(nèi)存大量地定義變量的話,將會(huì)造成非常嚴(yán)重的內(nèi)存浪費(fèi)(內(nèi)存碎片化),浪費(fèi)的內(nèi)存 = 6 * N(N表示結(jié)構(gòu)體變量的個(gè)數(shù))。比如用結(jié)構(gòu)體Text1定義1000個(gè)結(jié)構(gòu)體變量,浪費(fèi)的內(nèi)存 = 6 * 1000 = 6000 Byte(非常接近6K內(nèi)存)。
好了,假如我是懂得內(nèi)存對(duì)齊的原理的,那么我可以這樣去優(yōu)化結(jié)構(gòu)體Text1。
接著,從Debug里觀察看看:
最后,去Memory1觀察內(nèi)存的分布情況:
再將結(jié)構(gòu)體Text1的內(nèi)存分布提取出來分析一下,將成員b與成員c互換位置后,被填充的字節(jié)數(shù)變成2,成功地優(yōu)化了4個(gè)字節(jié)的碎片。如果用Text1的結(jié)構(gòu)體去定義1000個(gè)結(jié)構(gòu)體變量的話,那么1000 * 6的碎片內(nèi)存被優(yōu)化成1000 * 2的碎片內(nèi)存,成功改善了1000 * 4(接近4K的內(nèi)存)啊。
三、在內(nèi)存對(duì)齊話題下的sizeof與offsetof宏
首先,在main.c包含頭文件stddef.h。
回到最初的例子,代碼如下:
3.1、sizeof
通過sizeof操作符能夠得出一個(gè)結(jié)構(gòu)的整體長(zhǎng)度,包括因邊界對(duì)齊而跳過的那些字節(jié)。
3.2、offsetof宏
考慮到內(nèi)存對(duì)齊的因素,想確定結(jié)構(gòu)體里某個(gè)成員的實(shí)際位置,可以使用offsetof宏得到。比如我想得到成員b在結(jié)構(gòu)體Test1的實(shí)際位置(包括內(nèi)存對(duì)齊因素)。
3.3、Debug
進(jìn)入Debug模式觀察sizeof與offsetof的返回值分別是12與4。
總結(jié)
本篇文章就到這里了,希望能給你帶來幫助,也希望您能夠多多關(guān)注腳本之家的更多內(nèi)容!
相關(guān)文章
C++設(shè)計(jì)模式之組合模式(Composite)
這篇文章主要為大家詳細(xì)介紹了C++設(shè)計(jì)模式之組合模式Composite,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-04-04C語(yǔ)言中對(duì)字母進(jìn)行大小寫轉(zhuǎn)換的簡(jiǎn)單方法
這篇文章主要介紹了C語(yǔ)言中對(duì)字母進(jìn)行大小寫轉(zhuǎn)換的簡(jiǎn)單方法,是C語(yǔ)言入門學(xué)習(xí)中的基礎(chǔ)知識(shí),需要的朋友可以參考下2015-08-08C語(yǔ)言二叉樹的三種遍歷方式的實(shí)現(xiàn)及原理
這篇文章主要介紹了C語(yǔ)言二叉樹的三種遍歷方式的實(shí)現(xiàn)及原理,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-07-07