91欧美超碰AV自拍|国产成年人性爱视频免费看|亚洲 日韩 欧美一厂二区入|人人看人人爽人人操aV|丝袜美腿视频一区二区在线看|人人操人人爽人人爱|婷婷五月天超碰|97色色欧美亚州A√|另类A√无码精品一级av|欧美特级日韩特级

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

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

3天內不再提示

C語言內存泄露問題很嚴重,如何應對?

電子設計 ? 來源:電子設計 ? 作者:電子設計 ? 2020-10-30 09:58 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

1. 前言
最近部門不同產品接連出現(xiàn)內存泄漏導致的網上問題,具體表現(xiàn)為單板在現(xiàn)網運行數(shù)月以后,因為內存耗盡而導致單板復位現(xiàn)象。

一方面,內存泄漏問題屬于低級錯誤,此類問題遺漏到現(xiàn)網,影響很壞;另一方面,由于內存泄漏問題很可能導致單板運行固定時間以后就復位,只能通過批量升級才能解決,實際影響也很惡劣。

同時,接連出現(xiàn)此類問題,尤其是其中一例問題還是我們老員工修改引入,說明我們不少員工對內存泄漏問題認識還是不夠深刻的。

本文通過介紹內存泄漏問題原理及檢視方法,希望后續(xù)能夠從編碼檢視環(huán)節(jié)就杜絕此類問題發(fā)生。

說明:預防內存泄漏問題有多種方法,如加強代碼檢視、工具檢測和內存測試等,本文聚集于開發(fā)人員能力提升方面。

2. 內存泄漏問題原理
2.1 堆內存在 C 代碼中的存儲方式
內存泄漏問題只有在使用堆內存的時候才會出現(xiàn),棧內存不存在內存泄漏問題,因為棧內存會自動分配和釋放。

C 代碼中堆內存的申請函數(shù)是 malloc,常見的內存申請代碼如下:

左右滑動查看全部代碼>>>

char *info = NULL; /**轉換后的字符串**/
info = (char*)malloc(NB_MEM_SPD_INFO_MAX_SIZE);
if( NULL == info)
{
(void)tdm_error("malloc error!/n");
return NB_SA_ERR_HPI_OUT_OF_MEMORY;
}

由于 malloc 函數(shù)返回的實際上是一個內存地址,所以保存堆內存的變量一定是一個指針(除非代碼編寫極其不規(guī)范)。

再重復一遍,保存堆內存的變量一定是一個指針,這對本文主旨的理解很重要。當然,這個指針可以是單指針,也可以是多重指針。

malloc 函數(shù)有很多變種或封裝,如 g_malloc、g_malloc0、VOS_Malloc 等,這些函數(shù)最終都會調用 malloc 函數(shù)。

2.2 堆內存的獲取方法
看到本小節(jié)標題,可能有些同學有疑惑,上一小節(jié)中的 malloc 函數(shù),不就是堆內存的獲取方法嗎?

的確是,通過 malloc 函數(shù)申請是最直接的獲取方法,如果只知道這種堆內存獲取方法,就容易掉到坑里了。一般的來講,堆內存有如下兩種獲取方法:

方法一:將函數(shù)返回值直接賦給指針,一般表現(xiàn)形式如下:

左右滑動查看全部代碼>>>

char *local_pointer_xx = NULL;
local_pointer_xx = (char*)function_xx(para_xx, …);


該類涉及到內存申請的函數(shù),返回值一般都指針類型,例如:

左右滑動查看全部代碼>>>

GSList* g_slist_append (GSList *list, gpointer data);


方法二:將指針地址作為函數(shù)返回參數(shù),通過返回參數(shù)保存堆內存地址,一般表現(xiàn)形式如下:

左右滑動查看全部代碼>>>

int ret;
char *local_pointer_xx = NULL; /**轉換后的字符串**/
ret = (char*)function_xx(..., &local_pointer_xx, ...);


該類涉及到內存申請的函數(shù),一般都有一個入參是雙重指針,例如:

左右滑動查看全部代碼>>>

__STDIO_INLINE _IO_ssize_t;
getline (char **__lineptr, size_t *__n, FILE *__stream);
前面說通過 malloc 申請內存,就屬于方法一的一個具體表現(xiàn)形式。其實這兩類方法的本質是一樣的,都是函數(shù)內部間接申請了內存,只是傳遞內存的方法不一樣,方法一通過返回值傳遞內存指針,方法二通過參數(shù)傳遞內存指針。

2.3 內存泄漏三要素
最常見的內存泄漏問題,包含以下三個要素:

要素一:函數(shù)內有局部指針變量定義;

要素二:對該局部指針有通過上一小節(jié)中“兩種堆內存獲取方法”之一獲取內存;

要素三:在函數(shù)返回前(含正常分支和異常分支)未釋放該內存,也未保存到其它全局變量或返回給上一級函數(shù)。

2.4 內存釋放誤區(qū)
稍微使用過 C 語言編寫代碼的人,都應該知道堆內存申請之后是需要釋放的。但為何還這么容易出現(xiàn)內存泄漏問題呢?

一方面,是開發(fā)人員經驗不足、意識不到位或一時疏忽導致;另一方面,是內存釋放誤區(qū)導致。很多開發(fā)人員,認為要釋放的內存應該局限于以下兩種:

1) 直接使用內存申請函數(shù)申請出來的內存,如 malloc、g_malloc 等;

2)該開發(fā)人員熟悉的接口中,存在內存申請的情況,如 iBMC 的兄弟,都應該知道調用如下接口需要釋放 list 指向的內存:

左右滑動查看全部代碼>>>

dfl_get_object_list(const char* class_name, GSList **list);
按照以上思維編寫代碼,一旦遇到不熟悉的接口中需要釋放內存的問題,就完全沒有釋放內存的意識,內存泄漏問題就自然產生了。

3. 內存泄漏問題檢視方法
檢視內存泄漏問題,關鍵還是要養(yǎng)成良好的編碼檢視習慣。與內存泄漏三要素對應,需要做到如下三點:

1) 在函數(shù)中看到有局部指針,就要警惕內存泄漏問題,養(yǎng)成進一步排查的習慣

2) 分析對局部指針的賦值操作,是否屬于前面所說的“兩種堆內存獲取方法”之一,如果是,就要分析函數(shù)返回的指針到底指向啥?

是全局數(shù)據(jù)、靜態(tài)數(shù)據(jù)還是堆內存?對于不熟悉的接口,要找到對應的接口文檔或源代碼分析;又或者看看代碼中其它地方對該接口的引用,是否進行了內存釋放;

3) 如果確認對局部指針存在內存申請操作,就需要分析該內存的去向,是會被保存在全局變量嗎?又或者會被作為函數(shù)返回值嗎?如果都不是,就需要排查函數(shù)所有有”return“的地方,保證內存被正確釋放。

內存泄漏是比較難查的 bug 之一?有什么查找技巧嗎?歡迎留言交流~

審核編輯 黃昊宇

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

    關注

    183

    文章

    7644

    瀏覽量

    145588
  • 內存泄露
    +關注

    關注

    0

    文章

    7

    瀏覽量

    2165
收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評論

    相關推薦
    熱點推薦

    keil中c語言的動態(tài)分配內存

    C程序中,通常將內存劃分為以下六個區(qū)域: (1)內核區(qū)域。這塊區(qū)域是操作系統(tǒng)的,用戶不能使用。 (2)棧區(qū)。主要用于存放運行函數(shù)而分配的局部變量、函數(shù)參數(shù)、返回數(shù)據(jù)、返回地址等。棧內存分配運算內置
    發(fā)表于 01-21 06:04

    芯片買賣是人民幣玩家的游戲普通人慎入,賭錯后果很嚴重。元器件

    元器件
    芯廣場
    發(fā)布于 :2026年01月16日 16:03:42

    C語言嵌入式系統(tǒng)編程注意事項-內存操作

    C語言嵌入式系統(tǒng)編程注意事項之內存操作 在嵌入式系統(tǒng)的編程中,常常要求在特定的內存單元讀寫內容,匯編有對應的MOV指令,而除C/
    發(fā)表于 01-04 07:31

    C語言內存池使用

    C語言內存管理,從來都是一個讓人頭禿的問題。要想更自由地管理內存,就必須去堆中申請,然后還需要考慮何時釋放,萬一釋放不當,或者沒有及時釋放,造成的后果都是難以估量的。 當然如果就這
    發(fā)表于 12-11 07:57

    C語言的編程技巧

    一個成員是一個未知大小的數(shù)組,適用于動態(tài)分配內存并關聯(lián)一個可變長度的數(shù)組。? ?3、匿名結構體和聯(lián)合體?:C語言允許在結構體或聯(lián)合體中定義不帶標簽的內部結構體或聯(lián)合體,簡化代碼結構。 ?4
    發(fā)表于 11-27 06:46

    C語言特性

    訪問內存地址,對內存中的數(shù)據(jù)進行讀寫操作,還可以控制硬件的寄存器,實現(xiàn)對硬件設備的精確控制。這種底層操作的能力,使得 C 語言在嵌入式開發(fā)中能夠充分發(fā)揮硬件的優(yōu)勢,實現(xiàn)各種復雜的功能。
    發(fā)表于 11-24 07:01

    WebGL/Canvas 內存泄露分析

    在構建高性能、長周期運行的 WebGL/Canvas 應用(如 3D 編輯器、數(shù)據(jù)可視化平臺)時,內存管理是一個至關重要且極具挑戰(zhàn)性的課題。 開發(fā)者通常面臨的內存泄漏問題,其根源遠比簡單
    的頭像 發(fā)表于 10-21 11:40 ?408次閱讀
    WebGL/Canvas <b class='flag-5'>內存</b><b class='flag-5'>泄露</b>分析

    STM32+DP83848跑10M可以,100M丟包很嚴重,請問有人遇到過嗎?

    大佬們,stm32驅動dp83848,跑10M可以,100M丟包很嚴重,請問有人遇到過嗎
    發(fā)表于 08-20 10:04

    靈活高效ZBUFF — C內存數(shù)據(jù)操作庫:優(yōu)化內存管理的利器

    C語言開發(fā)中,高效的內存管理是提升程序性能的關鍵。ZBUFF作為一款靈活高效的內存數(shù)據(jù)操作庫,通過優(yōu)化內存分配與釋放機制,為開發(fā)者提供了更
    的頭像 發(fā)表于 08-14 18:01 ?694次閱讀
    靈活高效ZBUFF — <b class='flag-5'>C</b><b class='flag-5'>內存</b>數(shù)據(jù)操作庫:優(yōu)化<b class='flag-5'>內存</b>管理的利器

    靈活高效雙引擎驅動:ZBUFF讓C語言內存操作更智能!

    高性能系統(tǒng)。 一、ZBUFF核心庫常用函數(shù) 如果小伙伴們此前沒有接觸過C語言或者不精通C語言,把ZBUFF核心庫當成新庫來學習即可,建議先從熟悉相關函數(shù)的功能及其參數(shù)意義入手。 感興趣
    的頭像 發(fā)表于 08-11 13:27 ?589次閱讀
    靈活高效雙引擎驅動:ZBUFF讓<b class='flag-5'>C</b><b class='flag-5'>語言</b><b class='flag-5'>內存</b>操作更智能!

    主流的 MCU 開發(fā)語言為什么是 C 而不是 C++?

    在單片機的地界兒里,C語言穩(wěn)坐中軍帳,C++想分杯羹?難嘍。咱電子工程師天天跟那針尖大的內存空間較勁,C++那些花里胡哨的玩意兒,在這兒真玩
    的頭像 發(fā)表于 05-21 10:33 ?1040次閱讀
    主流的 MCU 開發(fā)<b class='flag-5'>語言</b>為什么是 <b class='flag-5'>C</b> 而不是 <b class='flag-5'>C</b>++?

    如何讓SDK slfifosync支持FPGA 100MHz?

    CY_FX_SLFIFO_GPIF_16_32BIT_CONF_SELECT 改成0(16-BIT data bus). 但是從PC上讀到的數(shù)據(jù)掉失很嚴重, 我想SDK slfifosync支持FPGA 100MHz?
    發(fā)表于 05-06 08:11

    深入理解C語言C語言循環(huán)控制

    C語言編程中,循環(huán)結構是至關重要的,它可以讓程序重復執(zhí)行特定的代碼塊,從而提高編程效率。然而,為了避免程序進入無限循環(huán),C語言提供了多種循環(huán)控制語句,如break、continue和
    的頭像 發(fā)表于 04-29 18:49 ?2046次閱讀
    深入理解<b class='flag-5'>C</b><b class='flag-5'>語言</b>:<b class='flag-5'>C</b><b class='flag-5'>語言</b>循環(huán)控制

    C語言的歷史及程序介紹

    電子發(fā)燒友網站提供《C語言的歷史及程序介紹.pdf》資料免費下載
    發(fā)表于 04-09 16:10 ?0次下載

    快速搞懂C語言程序內存分區(qū)!

    在程序運行過程中,操作系統(tǒng)會根據(jù)程序的需要,將內存劃分為多個功能不同的區(qū)段,以便更高效地管理內存資源和確保程序的穩(wěn)定運行。不同的內存區(qū)段負責存儲不同類型的數(shù)據(jù)和代碼,涵蓋了從程序指令、全局變量
    的頭像 發(fā)表于 03-14 17:37 ?1568次閱讀
    快速搞懂<b class='flag-5'>C</b><b class='flag-5'>語言</b>程序<b class='flag-5'>內存</b>分區(qū)!