精品国产人成在线_亚洲高清无码在线观看_国产在线视频国产永久2021_国产AV综合第一页一个的一区免费影院黑人_最近中文字幕MV高清在线视频

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

單片機上用malloc()是個坑,有隱患?

無際單片機編程 ? 來源:無際單片機編程 ? 2024-02-22 15:53 ? 次閱讀

單片機研發前幾年,一直沒用過動態內存分配的功能,但是如果想成為軟件架構設計師,這是繞不過的一道坎。

其實單片機很少使用c標準庫自帶的malloc()函數去動態分配內存,除非,你看老板不爽...

因為有缺陷,文章后面會提及。

一般是工程師借助現成的參考代碼,然后重新設計內存管理代碼,改進動態內存分配算法

不過代碼難度挺大,c語言功底不好的,看到代碼會失聲痛哭....

不信?我裝個逼給你看!

下圖,是以前自己借鑒(抄襲),再吃透,后改進的內存管理代碼,測試已解決內存碎片問題。

43ddafca-d157-11ee-a297-92fbcf53809c.png

43f53000-d157-11ee-a297-92fbcf53809c.png

代碼沒多少,卻讓我充分感受到,編程語言只是工具,編程思維才是靈魂

本來是計劃用在無際單片機特訓營項目6的,但是感覺太復雜了,怕老鐵們學著學著來罵我,所以這代碼就失寵了。

新手,或者有些一直從事比較簡單產品工程師,可能無法理解,malloc的應用場景,到底在哪里?

我以無際單片機特訓營項目3來舉例幾個使用場景,或許你就明白了。

1.malloc使用場景1:動態任務創建

學過我們項目3的老鐵,不知道有沒有發現一個問題。

在用我們那個"小系統"創建任務的時候,不夠靈活,每次增加新的任務,要手動在頭文件增加任務ID

441628d2-d157-11ee-a297-92fbcf53809c.png

這樣做的目的,是為了給下面這個任務結構體數組OS_Task,分配固定的內存空間。

44257da0-d157-11ee-a297-92fbcf53809c.png

最后才是創建任務。

44347c74-d157-11ee-a297-92fbcf53809c.png

如果使用動態內存分配,就可以省略前面步驟,直接創建任務,在任務創建函數里通過動態內存分配函數,給任務動態開辟一塊內存,如果對RTOS有研究,應該知道我在講什么..

2.malloc使用場景2:探測器列表

項目3是需要和不同的探測器(遙控器、門磁探測器、紅外探測器、煙霧探測器等等)組網使用的。

我們做了一個菜單,在OLED屏上顯示已經組網的探測器列表。

44428d14-d157-11ee-a297-92fbcf53809c.png

每個主機,已經組網的探測器數量都不一樣,有些主機最多支持組網255個探測器。

每個探測器都有探測器ID、組網標志、序號、名稱等參數

44562c48-d157-11ee-a297-92fbcf53809c.png

那是不是意味著,如果主機最大支持255個探測器,如果沒有動態內存分配,就要提前定義能夠存儲255個探測器參數的結構體數組?

事實上,我想到兩種方式。

第一種是先存到外部的flash里,用到了再讀出來,程序操作起來麻煩,而且效率慢,優點是省RAM

第二種是直接分配255個探測器的靜態存儲空間,程序操作爽,效率高,但費RAM,還好特么用了STM32

我這個探測器列表菜單,用的是第二種方式,因為我主機對探測器數量的上限設置是20個,哈哈。

446149b6-d157-11ee-a297-92fbcf53809c.png

對于這種功能需求,王炸的解決方案,就是用動態內存分配了!用時分配,用完釋放!

但是,不建議直接用malloc()!!!

其實我第一次接觸內存管理,是做藍牙產品,用TI協議棧的時候。

當時有點奇怪的是,c語言標準庫有malloc()動態內存分配和free()內存釋放函數,osal系統為什么要自己寫osal_mem_alloc()和osal_mem_free()?

直到后面自己做了一些復雜點的項目,自己也調過內存管理代碼,才理解。

單片機上用malloc(),是個坑,有隱患。

我覺得內存碎片,是萬惡之源。

malloc()函數本身只是動態分配內存,并沒有直接解決內存碎片問題。

什么是內存碎片?

剛開始,我也不理解,什么是內存碎片,網上搜了很多相關內容,越繞越暈。

我嘗試用通俗易懂的語言,長話短說,能不能理解,看基礎和悟性了。

內存碎片分為兩種:

1.外部碎片

想象一下,有一個大型的圖書館,圖書館的書架上擺滿了各種各樣的書籍,這些書籍大小可能不一樣,書籍就像內存中的內存塊(已被動態分配的內存),書架上的空位代表空閑內存(未被分配的內存或者被釋放的內存)。

當讀者借閱書籍后,書架上會留下一些空位。隨著時間的推移,這些空位可能變得非常分散,就像散落在書架上的小塊空間。

如果突然要存放一本很大很厚的書,到書架上時,可能很難找到足夠大的連續空位來放置這本書。

那如果往后要存放的書,都是很大很厚的呢?

是不是雖然空位很多,但就是放不進去?那這塊空間是不是就浪費掉了?

在內存分配時也是同理,如果頻繁地用malloc()分配很多零散的內存塊,每個內存塊占用的字節數都不一樣。

當這些內存塊使用完,被free()釋放以后,這塊空閑內存,比如是8個字節,那下次,再有動態分配內存需求時,除非是8個字節或者以下才能使用這個內存塊,如果是8個字節以上,這塊內存塊就相當于一直用不上,就浪費了。

所以說,即使總的空閑空間足夠,但由于碎片化,也不好滿足大內存塊的分配請求。

這就是,在內存管理中,外部內存碎片化會導致系統無法為新的內存請求,分配足夠的連續內存空間注意連續內存空間很重要,如果不連續,處理器就要不斷從整個內存池去尋找,這樣讀取效率就會變低,這是內存碎片的影響。

2.內部碎片

內部內部碎片就是分配了內存空間,但未被使用的部分。

為此,我做了一個實驗:

446f9796-d157-11ee-a297-92fbcf53809c.png

上圖程序里,我給p1和p2分配1個字節內存,實際卻分配了8個字節的空間,在釋放前這7個字節都不能再被分配,相當于7個字節空間就浪費了。

以上兩種碎片的產生,會讓程序產生一種很尷尬的現象,就是明明有很多空閑內存,但總是分配失敗,甚至導致程序死機,而且這種死機現象,通常是沒有規律的。

印象中,我以前解決碎片問題的方法,大概是,內存釋放后,把該內存塊后面所有已分配的內存塊往前遷移。

447a7bf2-d157-11ee-a297-92fbcf53809c.png

其實內存管理,就是開辟一個很大的數組,稱內存池

449fd1fe-d157-11ee-a297-92fbcf53809c.png

然后后面所有的功能,比如動態內存分配,內存釋放,都是基于這個大數組去完成,會涉及到數據結構,涉及到算法。

所以,數據結構和算法,這個時候針對性去學是最合適的

很多人項目都沒做過,就去學,沒什么鳥用,學完也不知道能干嘛。

說到這里,我相信你應該沒有單片機上用malloc()的勇氣了吧?

小批量生產可能測不出來,大批量生產就會陸續出現死機現象了,碰到了,就偷偷躲廁所里哭吧,這種問題能找死個人!

至于很多人說的,比如單片機不用malloc(),是因為內存資源有限,個人人為不是問題本質,一般能用上動態內存分配的產品,單片機內存資源都比較大。

本質就是用malloc()容易產生內存碎片,從而會引發一系列的問題,比如數據讀取效率問題、穩定性問題等等...

PC上用malloc()估計也會存在內存碎片的問題,只是電腦內存動不動就上G,沒有嵌入式設備這么敏感,當然PC可能還有別的方式去解決碎片化問題,這塊我沒做過,不做表態。





審核編輯:劉清

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • 單片機
    +關注

    關注

    6032

    文章

    44516

    瀏覽量

    633042
  • 探測器
    +關注

    關注

    14

    文章

    2619

    瀏覽量

    72916
  • C語言
    +關注

    關注

    180

    文章

    7598

    瀏覽量

    136205
  • OLED屏
    +關注

    關注

    0

    文章

    162

    瀏覽量

    20823
  • malloc
    +關注

    關注

    0

    文章

    52

    瀏覽量

    70

原文標題:為什么單片機上的程序不建議使用malloc?

文章出處:【微信號:nanshuqg,微信公眾號:無際單片機編程】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏

    評論

    相關推薦

    淺談 malloc 函數在單片機上的應用

    聊聊 malloc函數 在單片機程序設計中怎么使用
    的頭像 發表于 05-18 09:35 ?2246次閱讀
    淺談 <b class='flag-5'>malloc</b> 函數在<b class='flag-5'>單片機上</b>的應用

    為什么在單片機上的程序不怎么使用malloc,而PC上經常使用?

    一樣跑在硬件上的,它們屬于一層次的。過去之所以沒有區分出單片機上的程序和PC機上的程序的一些差異,就是沒有弄明白這一點。由此,以前的一些疑惑也就解開了。為什么在單片機上的程序不怎么使
    發表于 05-03 13:33

    如何在單片機上也可正常使用動態內存分配

    51單片機內存動態分配序言最近玩51單片機碰到一問題,51中malloc函數并不能像在PC上一樣正常運行,這涉及到了內存池的概念。下面就來演示一下如何在
    發表于 11-19 07:36

    malloc的相關資料分享

    首先,malloc( )屬于標準C語言函數,當然可以在單片機上使用,如STM32可以先在啟動文件中設置heap的大小,再使用動態內存分配: Heap_Size EQU 0x00000200 \\也就
    發表于 11-26 08:27

    怎樣去解決單片機使用malloc產生內存泄露的問題呢

    為什么單片機使用malloc會導致內存泄露呢?怎樣去解決單片機使用malloc產生內存泄露的問題呢?
    發表于 01-27 06:23

    如何在單片機上摁鍵編輯信息可以在單片機上顯示?

    做一設計求指導,就是想在單片機上摁鍵編輯信息可以在單片機上顯示,并且能發送到電腦上,還能收到電腦的的信息。
    發表于 09-28 06:37

    32單片機上的uCOSII和FreeRTOS兩實時操作系統什么區別?

    32單片機上的uCOSII和FreeRTOS兩實時操作系統什么區別啊,在上班之后一般是的哪一類實時操作系統比較多啊
    發表于 10-27 08:07

    Atmel AVR 單片機上網方案

    Atmel AVR 單片機上網方案
    發表于 01-14 15:04 ?6次下載

    淺談單片機上電復位后端口的狀態

    量避免處于輸出狀態(無論是輸出低還是輸出高) 為什么要這樣說呢?因為單片機外圍電路的動作就是靠單片機端口輸出低電平或者高電平來控制的。假如單片機端口一上電就處于輸出高或者低電平的狀態,那么很容易出現誤動作。例如,
    的頭像 發表于 11-30 18:17 ?4032次閱讀

    分享可應用于單片機的內存管理模塊mem_malloc

    空間不足而分配失敗,從而導致系統崩潰,因此應該慎用,或者自己實現內存管理。 mem_malloc就是一不會產生內存碎片的、適合單片機使用的內存管理模塊。
    的頭像 發表于 06-25 08:54 ?2982次閱讀
    分享可應用于<b class='flag-5'>單片機</b>的內存管理模塊mem_<b class='flag-5'>malloc</b>

    關于stm32 MCU申請動態內存malloc的認識

    首先,malloc( )屬于標準C語言函數,當然可以在單片機上使用,如STM32可以先在啟動文件中設置heap的大小,再使用動態內存分配: Heap_Size EQU 0x00000200 \\也就
    發表于 11-18 16:21 ?14次下載
    關于stm32 MCU申請動態內存<b class='flag-5'>malloc</b>的認識

    記錄單片機使用malloc產生內存泄露的問題及解決方法

    項目場景:單片機使用malloc產生內存泄露的問題問題描述:bug1:創建了一結構體指針,通過malloc動態開辟內存的方式開辟了一段內存空間,然后進行寫入數據修改數據的操作,但是下
    發表于 12-03 10:21 ?8次下載
    記錄<b class='flag-5'>單片機</b>使用<b class='flag-5'>malloc</b>產生內存泄露的問題及解決方法

    89系列單片機上機指導

    89系列單片機上機指導
    發表于 06-13 14:20 ?2次下載

    如何在單片機中使用malloc函數

    但是每個嵌入式 RTOS 都會有自己的內存管理方式,本文就來聊聊我對 malloc 函數在單片機程序設計中的一些看法。 本文并不是要說明在單片機中怎么使用 malloc函數,而是
    的頭像 發表于 04-24 09:50 ?2469次閱讀
    如何在<b class='flag-5'>單片機</b>中使用<b class='flag-5'>malloc</b>函數

    如何實現一malloc

    任何一用過或學過C的人對malloc都不會陌生。大家都知道malloc可以分配一段連續的內存空間,并且在不再使用時可以通過free釋放掉。但是,許多程序員對malloc背后的事情并不
    的頭像 發表于 11-13 14:31 ?737次閱讀
    如何實現一<b class='flag-5'>個</b><b class='flag-5'>malloc</b>