当前位置:文档之家› 软件编程低级错误:内存泄漏解析

软件编程低级错误:内存泄漏解析


致原来本地目录下文件数比较小,小于等1000时没有内存泄漏;
而当本地目录下的文件比较多,大于1000时,就会导致内存泄漏 。 【举一反三】开发人员在使用指针数组时,要特别注意,确保在释放 数组时,数组中的每个元素指针是否已经提前被释放了,这样才不 会导致内存泄漏。
HUAWEI TECHNOLOGIES CO., LTD. Huawei Confidential Page 11
【问题描述&定位】代码飞检发现如下代码: rc = np_ss_semB_create(NP_SEM_EMPTY, NP_SEM_Q_FIFO, (g_ims_vport_base_info.qinq_base_info.sem)); if(rc != NP_RC_SUCCESS)/*申请信号量失败*/
【问题定位】先删除了pstStorageBuff,pstStorageBuff->pcData永远不可能被删除了 【举一反三】删除结构指针时,必须从底层向上层顺序删除
HUAWEI TECHNOLOGIES CO., LTD.
Huawei Confidential
Page 9
没有释放数组的成员指针
【问题描述】测试部对M产品进行压力和稳定性测试,模拟文件上传的场景,把本地目录下的3万个文件上传到另一台主机。发现上传程序在传送文件 过程中,内存在快速增长,通过ps auwx监控,发现该进程占用的内存每隔4分钟(一个周期)就突然增加20~30M的内存。 【问题定位】struct dirent **namelist;
重复分配内存
【问题描述】代码飞检发现如下代码: ULONG CQC_CmdNoDropLevelClass(VOID* pMsgRcv,VOID** ppMsgSnd) { /* 以下是从别处拷贝的代码 */ ulErrCode = CFG_CreateResMsgs(pMsgRcv, ppMsgSnd)); ……………… /* 拷贝代码结束 */ ……………… ulErrCode = CFG_CreateResMsgs(pMsgRcv, ppMsgSnd));
内存泄漏案例问题和纠正措施建议
HUAWEI TECHNOLOGIES CO., LTD.
Huawei Confidential
Page 3
异常出口处没有释放内存
【问题描述】代码飞检发现如下代码: pMsgDB_DEV = (PDBDevMsg)GetBuff( sizeof( DBDevMsg ), __LINE__); if( pMsgDB_DEV == NULL ) { return; } pMsgDBApp_To_Logic = (LPDBSelfMsg)GetBuff( sizeof(DBSelfMsg), __LINE__ ); if( pMsgDBApp_To_Logic == NULL ) {
HUAWEI TECHNOLOGIES CO., LTD.
Huawei Confidential
Page 10
没有释放数组的成员指针(续)
从上面的代码可以看是指针数组namelist由系统函数进行分配内存(
如【1】所示),内存释放时时分别由【2】【3】完成的。
但是中间有个条件,每次只取1000个文件,如果目录下的文件大于 1000就跳出,后面的就不会再管了(【2】没有执行到)。所以导
{
NP_SS_ASSERT(0, "Create qinq sem failed!"); return rc; } #if SOFT_Version rc = np_ss_semB_create(NP_SEM_EMPTY, NP_SEM_Q_FIFO, &(g_ims_vport_base_info.eqinq_base_info.sem)); if(rc != NP_RC_SUCCESS)/*申请信号量失败*/ { NP_SS_ASSERT(0, "Create qinq sem failed!"); return rc; } #endif …………………………. NP_FREE_SEM(g_ims_vport_base_info.qinq_base_info.sem); #if SOFT_Version NP_FREE_SEM(g_ims_vport_base_info.eqinq_base_info.sem); #endif return rc; //没有释放前面分配的信号量g_ims_vport_base_info.qinq_base_info.sem
{
NP_SS_ASSERT(0, "Create qinq sem failed!"); NP_FREE_SEM(g_ims_vport_base_info.qinq_base_info.sem); return rc;
}
#endif 。。。。。。。。。。。。 【举一反三】看见return要注意,要去前面找资源,特别要注意信号量、定时器等资源
………………
} 【举一反三】 代码Copy要小心
HUAWEI TECHNOLOGIES CO., LTD. Huawei Confidential
Page 12
没有释放传入定时器的内存
【问题描述】使用purify测试,发现上报MLK: 在我们的应用程序的对象中,由于在设置定时器时需要传递一个参数,这个参数的需要从堆中去获取,因为在后续的定时器超时回调时需要使用这个参 数。在对象中设置定时器的代码如下:
switch(userTimerID)
{ case pending_user_enroll_timer_id: { TString* ipport = reinterpret_cast<TString*>(pData); ... delete ipport;
}
... } } 在我们设置的定时器超时后,会自动调用onTimeOut这个函数,根据userTimerID来把所需要的参数转化为我们原来的数据类型,使用完成后在销毁 它。这看起来一切都很正常,new出来资源通过delete来进行释放,为什么出现了内存泄漏呢?
HUAWEI TECHNOLOGIES CO., LTD.
Huawei Confidential
Page 6
异常出口处没有释放信号量资源(续)
【纠正措施】第二个信号量申请失败return之前释放第一个申请的信号量 。。。。。。。。。。。。 #if SOFT_Version rc = np_ss_semB_create(NP_SEM_EMPTY, NP_SEM_Q_FIFO, &(g_ims_vport_base_info.eqinq_base_info.sem)); if(rc != NP_RC_SUCCESS)/*申请信号量失败*/
{
return; } 【问题定位】创建VC控制块失败时,return前没有删除AVL树中的节点
【举一反三】看见return要注意,要去前面找资源,特别要注意链表等数据结构中
的资源
HUAWEI TECHNOLOGIES CO., LTD.
Huawei Confidential
Page 5
异常出口处没有释放信号量资源
编程习惯引起的。不遵守编程规范的代码,往往也是最不可靠的代码。
• 本胶片收集了常见的内存泄漏案例,给出了相应的纠正措施。对应的编程规范:防 止内存泄漏;函数中分配的内存,在函数退出之前要释放
HUAWEI TECHNOLOGIES CO., LTD. Huawei Confidential Page 2
HUAWEI TECHNOLOGIES CO., LTD. Huawei Confidential Page 7
异常出口处没有释放GUI资源
【问题描述】网上问题案例: CBitmap bmp; CBitmap* pOldBmp; bmp.LoadBitmap(IDB_MYBMP); pOldBmp = pDC->SelectObject( &bmp ); if( Something() ) {
Security Level:
Internal Public
公司常见软件编程低级 错误:内存泄漏
C语言软件编程规范工作组

HUAWEI TECHNOLOGIES CO., LTD.
Huawei Confidential
前言
• 这套材料作为编程规范的辅助材料,帮助大家理解编程规范背后的原理。 • C和C++语言是我司的主流编程语言,然而C/C++具有很多强大的语言特性,从而 导致C/C++非常复杂,使得代码更容易出现BUG、难以阅读和维护。 • 业界知名的编程规范都对C/C++容易出现问题的语言特性进行管理。例如MISRA (汽车工业软件可靠性联合会)制定的1998版的MISRAC规范指出,一些在C看来 可以接受,却存在隐患的地方有127处之多。2004版的MISRAC规范将针对C语言 的规则增加到了141条。 • 对于程序员来说,能工作的代码并不等于“好” 代码。“好”代码的指标很多,包 括可读性、可维护性、可移植性和可靠性等。出现网上问题的代码,大多数是不良
int n = scandir(path.c_str(), &namelist, 0, alphasort);【1】
int i = 0; for(i ; i < n; ++i) { string name = namelist[i]->d_name; free(namelist[i]); 【2】 if(name != ".." && name != ".") { ......... ++fileNum; if(MAX_SCAN_FILE_NUM == fileNum )//MAX_SCAN_FILE_NUM=1000 { break; } } } free(namelist); 【3】 return ;
相关主题