日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

C语言 | 内存对齐01 - 什么是内存对齐

發(fā)布時間:2025/3/15 编程问答 22 豆豆
生活随笔 收集整理的這篇文章主要介紹了 C语言 | 内存对齐01 - 什么是内存对齐 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

一、前言


在單片機下使用C語言編程時,內(nèi)存對齊的知識點必須掌握。掌握內(nèi)存對齊后,可以防止內(nèi)存碎片化,并且證明你有能力優(yōu)化內(nèi)存。嵌入式單片機開發(fā)的后階段,無非就是優(yōu)化內(nèi)存與優(yōu)化代碼執(zhí)行效率。

二、內(nèi)存對齊


先看如下代碼:

結(jié)構(gòu)體Test1占用了多少字節(jié)?如果事先不知道內(nèi)存對齊的話,答案肯定是:1個字節(jié)(char)+ 4個字節(jié)(int)+ 1個字節(jié)(char) = 6個字節(jié)。
事實上,Test1結(jié)構(gòu)體占用了12個字節(jié),從DEBUG模式下Watch1觀察:

OK,不就猜少了6個字節(jié)嗎?有什么影響嗎?先不說影響吧,咱們先來看看單片機內(nèi)存里的實際情況。從上圖看到,結(jié)構(gòu)體變量的首地址是0x200018F4,通過Keil的Memory1可以看到結(jié)構(gòu)體Text1在內(nèi)存的分布,如下圖所示。

將Test1的內(nèi)存分布提取出來,如下圖所示,因為內(nèi)存對齊的原因,有6個字節(jié)被填充了。換句話說,這6個字節(jié)被浪費了,無法被其他資源使用了(因為編譯器將這些內(nèi)存規(guī)劃給結(jié)構(gòu)體Test1了)。此時,如果使用結(jié)構(gòu)體Text1在堆內(nèi)存大量地定義變量的話,將會造成非常嚴重的內(nèi)存浪費(內(nèi)存碎片化),浪費的內(nèi)存 = 6 * N(N表示結(jié)構(gòu)體變量的個數(shù))。比如用結(jié)構(gòu)體Text1定義1000個結(jié)構(gòu)體變量,浪費的內(nèi)存 = 6 * 1000 = 6000 Byte(非常接近6K內(nèi)存)。

好了,假如我是懂得內(nèi)存對齊的原理的,那么我可以這樣去優(yōu)化結(jié)構(gòu)體Text1。

接著,從Debug里觀察看看:

最后,去Memory1觀察內(nèi)存的分布情況:

再將結(jié)構(gòu)體Text1的內(nèi)存分布提取出來分析一下,將成員b與成員c互換位置后,被填充的字節(jié)數(shù)變成2,成功地優(yōu)化了4個字節(jié)的碎片。如果用Text1的結(jié)構(gòu)體去定義1000個結(jié)構(gòu)體變量的話,那么1000 * 6的碎片內(nèi)存被優(yōu)化成1000 * 2的碎片內(nèi)存,成功改善了1000 * 4(接近4K的內(nèi)存)啊。

三、在內(nèi)存對齊話題下的sizeof與offsetof宏


首先,在main.c包含頭文件stddef.h。

回到最初的例子,代碼如下:

3.1、sizeof

通過sizeof操作符能夠得出一個結(jié)構(gòu)的整體長度,包括因邊界對齊而跳過的那些字節(jié)。

3.2、offsetof宏

考慮到內(nèi)存對齊的因素,想確定結(jié)構(gòu)體里某個成員的實際位置,可以使用offsetof宏得到。比如我想得到成員b在結(jié)構(gòu)體Test1的實際位置(包括內(nèi)存對齊因素)。

3.3、Debug

進入Debug模式觀察sizeof與offsetof的返回值分別是12與4。

總結(jié)

以上是生活随笔為你收集整理的C语言 | 内存对齐01 - 什么是内存对齐的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。