应用程序发生 Detected memory leaks!内存泄漏 一直程序员面对的是一个很痛苦的问题,要查出泄漏的地方有时候需要大半天甚至更长时间。这里讲讲我的一些查找内存泄漏以及避免内存泄漏的一些经验
1.数组相关
#define ITEM_COUNT 30
WORD m_arrRreset[ITEM_COUNT] = {0};
for (int i =0i < ITEM_COUNT; i++)
{
m_arrRreset[i] =i*6;
}
memcpy(m_arrRreset, m_arrRresetReq,sizeof(WORD)*FM_AM_PRESET_COUNT);
注意数组大小最好用const类型或宏定义,这样for循环遍历时,就不容易出现数组越界,内存操作函数中数据的大小也不要用具体数字(如 30)表示,避免造成混乱
2..指针相关
a.局部变量new了内存,用完了,就一定立马在函数内delete释放掉
#define BUFF_SIZE 256
void parsedata(char* lpCmd)
{
int nCmdLen = strlen(lpCmd);
BYTE pTempBuffer[BUFF_SIZE ] = {0};
BYTE *lpCurrentCmd = pTempBuffer;
if (nCmdLen > sizeof(pTempBuffer))
{
lpCurrentCmd = new BYTE[nCmdLen];
}
memcpy(lpCurrentCmd, lpCmd, nCmdLen);
....................................
....................................
//这里使用了一个技巧
//为了避免总是new内存,在数组能完全满足要求的情况下,直接用数组内存。非常高效完美的技巧。
if (lpCurrentCmd != pTempBuffer)
{
delete[] lpCurrentCmd;
lpCurrentCmd = NULL;
}
}
b. 指针作为返回值,在函数内部分配了内存(ps:局部的数组是不能作为函数返回值的,函数返回,内存就释放了,一定要用new的堆内存或静态变量),此种情况最容易,忘记释放内存。
char *getFullDstFilePath(char *strDirPath, char *strFileName)
{
char *fullName = NULL;
if ((fullName = (char *)malloc(strlen(strDirPath) + strlen(strFileName) )) == NULL)
{
memset(fullName, 0, strlen(fullName));
perror("Malloc fullName err");
}else
{
if (strDirPath[strlen(strDirPath) -1] == '/')
{
strcpy(fullName, strDirPath);
strcat(fullName, strFileName);
}else
{
strcpy(fullName, strDirPath);
strcat(fullName, "/");
strcat(fullName, strFileName);
}
}
return fullName; //返回堆内存,需要在函数外释放
}
函数调用
char *fullDstFilePath = NULL;
fullDstFilePath = getFullDstFilePath(strSrcDir, tdirname->d_name);
//虽然看不是fullDstFilePath分配了内存,但它指向的是malloc出来的堆内存,用完了,一定要释放
//if(fullDstFilePath!= NULL)
{
free(fullDstFilePath);
fullDstFilePath = NULL;
}
说明下free delete一个为NULL的指针,不会产生错误。大家可以自己尝试下。但文件close两次会产生错误
c。指针是函数形参的情况,需要传变量的地址进去
一般函数内部会检查此形参指针指向的是否是NULL内存。
int nCmdLen = 0;
BYTE* lpCmd = fpGetCmdBuf( hFp, &nCmdLen);
记得lpCmd 需要释放 见上面的情况 b. 指针作为返回值
函数原型
//lpCmdLen, [out], 返回该命令的长度,不能为NULL
BYTE* fpGetCmdBuf(HANDLE hFp, int* lpCmdLen);
d。 成员变量的释放,比较好解决,程序退出前,判断下是否指向的内存是NULL,不是就释放。
CInfo::~CInfo(void)
{
if ( m_pMap != NULL)
{
delete m_pMap;
m_pMap = NULL;
}
} //析构函数释放,就可以了
e。其他文件,句柄的释放,如文件,HANDLE,Socket的关闭同理。
本质上HANDLE就是指针
typedef void *HANDLE;
java有个try cache finilly 规范操作都是在finilly里面关闭文件,Socket。