- 1、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。。
- 2、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 3、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
- 4、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
- 5、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们。
- 6、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
- 7、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
TOP1 资源泄漏
资源泄漏(包括内存泄漏)是代码Review中最常见的错误之一,申请的每个资源必须明确由谁负责释放,何时释放,在何处释放;在异常/错误/返回处理中,保持清醒的头脑,清理战场。此处的资源还包括信号量、定时器、文件句柄等系统资源。
案例1.1
【问题描述】
宏里面有return语句导致内存泄漏案例一。
【问题分析】
1) 错误代码:
/*定义宏MODEL_ASSERT_RETFAIL*/
#define MODEL_ASSERT_RETFAIL (X)
{
if(X不合法)
return;
}
….//do something
MDSTrafficMsg* pMsg = VOS_AllocMsg( PID_MD, usLength );
if (NULL_PTR = = pMsg )
{
return ;
}
MDSDataListenerMgr *pDataListener = MDSDataInitalListenerMgr();
MODEL_ASSERT_RETFAIL(pDataListener);
2)分析:
使用宏MODEL_ASSERT_RETFAIL检查pDataListener是否合法,如果不合法,则直接返回,一旦返回,将导致前面通过指针pMsg申请到的消息包资源泄漏。
【纠正方法】
在宏MODEL_ASSERT_RETFAIL分支判断return前加上VOS_FreeMsg(PID_MD, pMsg ):该方法代码不够清晰,当用户看宏定义时,对VOS_FreeMsg(PID_MD, pMsg )不清楚还要跳回来看前面的代码。
设定该宏有返回值(指针不为空返回VOS_True,否则为VOS_False),将宏的return语句写在宏使用后(判断指针pDataListener合法性),若宏返回VOS_False释放pMsg并返回主调函数:该方法在遇到只判断一个指针的合法性时,浪费代码行、降低代码飞检效率且可能存在宏描述歧义等问题,简单的判断建议不使用宏。
【经验教训】
在XX版本的一个新模块的开发中,在TR5之前进行大话务量测试验证时,发现系统内存资源不足,当时TR5在即,这个问题影响到TR5过点,经过协调多个技术专家封闭攻关,花了三天时间终于发现问题所在,人力成本高达3000,对于内存使用,要确保释放闭环,所有异常退出点都需要释放内存。
案例1.2
【问题描述】
宏里面有return语句导致内存泄漏案例二。
【问题分析】
1) 错误代码:
头文件中的宏定义如下:
/#define NODE_RETURN_ERROR (p) { if (NULL == p) \
VOS_RECORD_ERROR(p);\
return NULL;\
}
文件中有个函数有如下代码段:
...//do something
pNode = (Node_Head_S *)malloc(sizeof(Node_Head_S));
NODE_RETURN_ERROR (pNode);//第一次使用宏
pBody = (Node_Body_S *)malloc(sizeof(Node_Body_S));
NODE_RETURN_ERROR (pBody); //第二次使用宏
...//do something
2)分析:
当通过指针pBody申请内存,然后通过宏NODE_RETURN_ERROR来判断是否申请成功,如果申请失败,则在宏NODE_RETURN_ERROR里面就直接返回了,这样导致通过指针pNode申请的内存泄漏了。
【纠正方法】
不使用宏,或将宏中的return语句写到宏调用后。
案例1.3
【问题描述】
异常出口没有释放应该释放的内存案例一。
【问题分析】
1) 错误代码:
// GetBuff函数的作用是什么动态内存
pMsgDB_DEV = (PDBDevMsg)GetBuff( sizeof( DBDevMsg ), __LINE__);
if ( NULL= = pMsgDB_DEV )
{
return;
}?
// GetBuff函数的作用是什么动态内存
pMsgDBApp_To_Logic = (LPDBSelfMsg)GetBuff( sizeof(DBSelfMsg), __LINE__ );
if ( NULL = = pMsgDBApp_To_Logic )
{
return;
}
2)分析:
在第2个return处,pMsgDB_DEV指向的内存丢失。
【纠正方法】
在第2个return处增加释放内存的操作。
【经验教训】
函数中有动态申请内存,要在函数范围内检查所有return语句是否释
文档评论(0)