一、前言
在單片機下使用C語言編程時,記憶體對齊的知識點必須掌握,掌握記憶體對齊后,可以防止記憶體碎片化,并且證明你有能力優化記憶體,嵌入式單片機開發的后階段,無非就是優化記憶體與優化代碼執行效率,
二、記憶體對齊
先看如下代碼:

結構體Test1占用了多少位元組?如果事先不知道記憶體對齊的話,答案肯定是:1個位元組(char)+ 4個位元組(int)+ 1個位元組(char) = 6個位元組,
事實上,Test1結構體占用了12個位元組,從DEBUG模式下Watch1觀察:

OK,不就猜少了6個位元組嗎?有什么影響嗎?先不說影響吧,咱們先來看看單片機記憶體里的實際情況,從上圖看到,結構體變數的首地址是0x200018F4,通過Keil的Memory1可以看到結構體Text1在記憶體的分布,如下圖所示,

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

好了,假如我是懂得記憶體對齊的原理的,那么我可以這樣去優化結構體Text1,

接著,從Debug里觀察看看:

最后,去Memory1觀察記憶體的分布情況:

再將結構體Text1的記憶體分布提取出來分析一下,將成員b與成員c互換位置后,被填充的位元組數變成2,成功地優化了4個位元組的碎片,如果用Text1的結構體去定義1000個結構體變數的話,那么1000 * 6的碎片記憶體被優化成1000 * 2的碎片記憶體,成功改善了1000 * 4(接近4K的記憶體)啊,

三、在記憶體對齊話題下的sizeof與offsetof宏
首先,在main.c包含頭檔案stddef.h,

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

3.1、sizeof
通過sizeof運算子能夠得出一個結構的整體長度,包括因邊界對齊而跳過的那些位元組,

3.2、offsetof宏
考慮到記憶體對齊的因素,想確定結構體里某個成員的實際位置,可以使用offsetof宏得到,比如我想得到成員b在結構體Test1的實際位置(包括記憶體對齊因素),

3.3、Debug
進入Debug模式觀察sizeof與offsetof的回傳值分別是12與4,

轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/293779.html
標籤:其他
