首页 > 资讯

嵌入式开发正确使用动态内存的方法(附示例代码)|环球关注

智通财经网 2023-05-06 08:09:04

扫描关注一起学嵌入式,一起学习,一起成长

尽管在开发过程中坚守原则和谨慎编程,甚至严格测试。然而内存泄露的错误还是难以杜绝,如何让系统自动查出内存泄露的错误呢?

一种比较好的方法是建立日志块,即每次分配内存时记录该内存块的指针和大小,释放时再去除该日志块,如果有内存泄露就会有对应的日志块记录这些内存没有释放,这样就可以提醒程序员进行查错。

有了上述日志块操作函数,再来实现动态内存分配与释放函数就很容易了。


(资料图片)

只有当处于 DEBUG 版本和打开内存调试 DMEM_DBG 时才进行日志登录,否则 MallocExt() 和 FreeExt() 函数与 malloc() 和 free() 是等价的,这样保证了系统处于发布版本时的性能(代码已经过严格测试,但这不是盈利的商业代码,即没有版权。但如果因代码错误带来的任何损失作者具有免责权利)。

代码部分:

首先定义日志块结构体:

/*Logofdynamicmemoryusage*/typedefstruct_dmem_log{struct_dmem_log*p_stNext;/*Pointtonextlog*/constvoid*p_vDMem;/*Pointtoallocatedmemorybythispointer*/INT32SiSize;/*Sizeoftheallocatedmemory*/}DMEM_LOG;

然后为该结构体开辟内存:

staticDMEM_LOG*s_pstFreeLog;/*Pointtofreelogpoolbythispointer*/staticINT8Us_byNumUsedLog;staticDMEM_LOG*s_pstHeadLog;/*Pointtousedlogchainbythispointer*//*Poolofdynamicmemorylog*/#defineNUM_DMEM_LOG20staticDMEM_LOGs_astDMemLog[NUM_DMEM_LOG];

下面是内存日志块的操作函数:初始化、插入日志和移除日志:

/***********************************************************InitializeDMemLog*Description:Initializelogofdynamicmemory*Arguments:void*Returns:void*Notes:**********************************************************/staticvoidInitDMemLog(void){INT16SnCnt;/*Initializepooloflog*/for(nCnt=0;nCnt0);DMEM_LOG*p_stLog;#ifOS_CRITICAL_METHOD==3OS_CPU_SRcpu_sr;#endif/*Getalogfromfreepool*/OS_ENTER_CRITICAL();/*Avoidraceconditionons_pstFreeLog*/if(!s_pstFreeLog){OS_EXIT_CRITICAL();PRINTF("AllocateDMemLogfailed.\r\n");return;}p_stLog=s_pstFreeLog;s_pstFreeLog=s_pstFreeLog->p_stNext;OS_EXIT_CRITICAL();/*Don"tneedtoprotectthislogthatisfreeonecurrently*/p_stLog->p_vDMem=p_vAddr;p_stLog->iSize=iSize;/*Putthislogintousedchain*/OS_ENTER_CRITICAL();/*Avoidracecondition*/p_stLog->p_stNext=s_pstHeadLog;s_pstHeadLog=p_stLog;++s_byNumUsedLog;OS_EXIT_CRITICAL();return;}/***********************************************************UnlogDMem*Description:Removeanallocatedmemoryfromlogpool*Arguments:constvoid*p_vAddrpointtoaddressofthisallocatedmemorybythispointer*Returns:void*Notes:**********************************************************/staticvoidUnlogDMem(constvoid*p_vAddr){ASSERT(p_vAddr);DMEM_LOG*p_stLog,*p_stPrev;#ifOS_CRITICAL_METHOD==3OS_CPU_SRcpu_sr;#endif/*Searchthelog*/OS_ENTER_CRITICAL();/*Avoidracecondition*/p_stLog=p_stPrev=s_pstHeadLog;while(p_stLog){if(p_vAddr==p_stLog->p_vDMem){break;/*Havefound*/}p_stPrev=p_stLog;p_stLog=p_stLog->p_stNext;/*Movetonextone*/}if(!p_stLog){OS_EXIT_CRITICAL();PRINTF("SearchLogfailed.\r\n");return;}/*Removefromusedpool*/if(p_stLog==s_pstHeadLog){s_pstHeadLog=s_pstHeadLog->p_stNext;}else{p_stPrev->p_stNext=p_stLog->p_stNext;}--s_byNumUsedLog;OS_EXIT_CRITICAL();/*Don"tneedtoprotectthislogthatisfreeonecurrently*/p_stLog->p_vDMem=NULL;p_stLog->iSize=0;/*Addintofreepool*/OS_ENTER_CRITICAL();/*Avoidracecondition*/p_stLog->p_stNext=s_pstFreeLog;s_pstFreeLog=p_stLog;OS_EXIT_CRITICAL();return;}

带日志记录功能的内存分配 MallocExt() 和内存释放 FreeExt() 函数:

/**********************************************************MallocExtension*Description:Mallocablockofmemoryandlogitifneed*Arguments:INT32SiSizesizeofdesiredallocatememory*Returns:void*NULL=failed,otherwise=pointerofallocatedmemory*Notes:**********************************************************/void*MallocExt(INT32SiSize){ASSERT(iSize>0);void*p_vAddr;p_vAddr=malloc(iSize);if(!p_vAddr){PRINTF("mallocfailedat%sline%d.\r\n",__FILE__,__LINE__);}else{#if(DMEM_DBG&&DBG_VER)memset(p_vAddr,0xA3,iSize);/*Fillgargagefordebug*/LogDMem(p_vAddr,iSize);/*Logmemoryfordebug*/#endif}returnp_vAddr;}/***********************************************************FreeExtension*Description:Freeablockofmemoryandunlogitifneed*Arguments:void*p_vMempointtothememorybythispointer*Returns:void*Notes:**********************************************************/voidFreeExt(void*p_vMem){ASSERT(p_vMem);free(p_vMem);#if(DMEM_DBG&&DBG_VER)UnlogDMem(p_vMem);/*Removememoryfromlog*/#endifreturn;}

原文:https://blog.csdn.net/jiangjunjie_2005/article/details/26937879

关注我【一起学嵌入式】,一起学习,一起成长。

觉得文章不错,点击“分享”、“赞”、“在看” 呗!

上一篇 下一篇
热文推荐 更多

嵌入式开发正确使用动态内存的方法(附示例代码)|环球关注

2023-05-06

今日快讯:全国快递业务量突破400亿件 折射经济持续向好信号

2023-05-06

PCIe4.0固态都不值钱了!2TB只能卖489元

2023-05-06

射频集成电路概念上市公司股票一览(2023/5/5)

2023-05-06

我的世界妖刀似蛭提升到什么状态怎么变成血刀_mc妖刀 似蛭 怎么合成

2023-05-06

太阳高度角与纬度的关系推导过程_太阳高度角与纬度的关系 世界快讯

2023-05-06

什么是不变资本和可变资本的差异_什么是不变资本和可变资本 当前资讯

2023-05-05

【播资讯】当好“红领巾”引路人 南曹小学开展辅导员队前教育培训

2023-05-05

1. 认识PS

2023-05-05

正和消保中心成立两周年:解决2.4万余件投诉和调解案件 涉及金额超过24亿元-世界播资讯

2023-05-05

今日视点:科学家根据“祝融号”返回的沙丘表面特征提出现代火星存在水

2023-05-05

团聚青春,逐梦警营!市南公安开展微视频比赛,获奖名单公布

2023-05-05

世界观点:德赛西威拟31.6亿元投建中西部基地项目 加码智能座舱及智能驾驶赛道

2023-05-05

奈雪发布“五一”成绩单:订单同比上涨120% 部分门店涨幅超800%_滚动

2023-05-05

触摸劳动之光 西南油气田输气管理处开展“走基层”活动

2023-05-05

苹果第二财季营收948亿美元,同比环比双双下滑但高于投行预期

2023-05-05

驳论不可知论最有力的论据是_驳斥不可知论最有力的论据是

2023-05-05

长城建设巴西首个新能源汽车工厂-世界热头条

2023-05-05

律师费用由谁承担_律师费用_天天热文

2023-05-05

韩国市民团体连日举行集会 强烈抗议日本核污水排海 天天快资讯

2023-05-05