低级错误案例集 内部公开 2 0 1 3 -5 -2 第1 页, 共7 6 页 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申请到的消息包资源泄漏。 低级错误案例集 内部公开 2 0 1 3 -5 -2 第2 页, 共7 6 页 【纠正方法】 在宏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_...