(原创不易,如需转载,请注明出处)
所有的内存泄漏,就是一个原因,分配内存后没有释放。
智能指针是通过在某些结构体(类)中增加一个计数模块,如果有引用,计数模块加一,如果某个地方释放引用,那么计数模块就减一,直到计数为零,智能指针能自动释放内存。
那么,如果没有智能指针模块,那么为了防止内存泄漏,一定要规范内存分配与释放的原则。我的个人原则就是谁申请,谁释放。在同一个函数内申请和释放。当然,在实际情况中,必然会出现这边申请,但是不能马上释放的情况,比如对某些数据在程序启动的时候需要初始化,那就讲究一个对称原则,在哪一层申请,就在程序的哪一层释放,这种情况就比较考验开发者的能力了。
万一你接手了一个垃圾代码,申请与释放比较随心所欲,那么出现内存泄漏,你就需要相应的一些手法了。我这里整理了几段代码,在我实际上检查内存泄漏的时候,还是非常有用的。代码如下:
// DetectMem.h
#ifndef _DETECT_MEM_H_
#define _DETECT_MEM_H_
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
extern FILE* fp;
int DetectInit(const char *chPath);
int DetectunInit();
#define RECORDINGMEM(addr) \
{\
char chInfo[1024]={0}; \
sprintf(chInfo,"0x%08X\t%d\t%s\n",addr,__LINE__,__FILE__); \
fwrite(chInfo,1,strlen(chInfo),fp); \
}
#define RECORDING_MALLOC(addr) \
{\
char chInfo[1024]={0}; \
sprintf(chInfo,"malloc\t0x%08X\t%d\t%s\n",addr,__LINE__,__FILE__); \
fwrite(chInfo,1,strlen(chInfo),fp); \
}
#define RECORDING_FREE(addr) \
{\
char chInfo[1024]={0}; \
sprintf(chInfo,"free\t0x%08X\t%d\t%s\n",addr,__LINE__,__FILE__); \
fwrite(chInfo,1,strlen(chInfo),fp); \
}
#define RECORDINLINE() \
{ \
char chInfo[1024]={"---------------------------"};\
fwrite(chInfo,1,strlen(chInfo),fp); \
}
#endif // !_DETECT_MEM_H_
// detectMem.c
#include "DetectMem.h"
FILE* fp = NULL;
int DetectInit(const char *chPath)
{
if (fp)
{
return -1;
}
fp = fopen(chPath, "wb+");
if (!fp)
{
return -2;
}
return 0;
}
int DetectunInit()
{
int nRet = 0;
if (!fp)
{
return -1;
}
nRet = fclose(fp);
if (!nRet)
{
return -2;
}
fp = NULL;
return 0;
}
在使用之前,先初始化一下,用于初始化保存日志的地址,然后再通过使用宏模块,实现内存的记录,最后释放一下,保存文件。根据日志从上往下分析内存的申请与释放情况。