http://blog.csdn.net/csynyk/article/details/2861979
在C语言论坛中看了dgarc发表的一个贴子后,按要求写了一段代码,可以实现内存分配的管理,避免内存泄漏,欢迎各位测试,如遇bug,敬请指出,我将进行有针对性的改进,然后重新贴出来。
要求如下:
题目:监控应用程序的内存申请和释放
描述:
不考虑多线程,使用动态单链表的方式进行操作,在应用程序申请内存时,需要把该内存节点信息插入链表进行记录,应用程序释放内存,把相应内存节点的信息从链表中删除,在应用程序退出时,如果链表仍然存在节点,说明存在内存泄露,应用程序不存在内存泄露,则链表为空。
MLCmalloc() 封装了malloc ,同时将信息插入链表操作
MLCfree() 封装了free ,同时将信息从链表中删除
程序代码:
下列代码在满足题目要求的同时,增加了对泄漏空间的检测和释放功能。
#include <stdio.h>
#include <string.h>
#include <windows.h>
#define _MC 1 // MLCmalloc()的标志
#define _FE 0 // MLCfree()的标志
#define _Check -1 //检测内存的标志
typedef struct _Memory //单向链表结构
{
unsigned int address;
struct _Memory *next;
}Mem, *LinkMem;
int MemoryContrl(size_t addr,char flag)
{
static Mem head; //保存链表头
LinkMem tmp=head.next, node=&head ;
if( _MC==flag ) //增加链表节点
{
while(tmp)
{
node=tmp;
tmp=tmp->next;
}
node->next=(LinkMem)malloc(sizeof(Mem));
if(node->next==NULL)
return 1; //分配失败!
node=node->next;
node->address=addr;
node->next=NULL;
}
else if( _FE==flag) //删除节点
{
while(tmp && (tmp->address!=addr))
{
node=tmp;
tmp=tmp->next;
}
if(tmp==NULL)
return -1; //free地址出错!
else
{
node->next=tmp->next;
free(tmp);
}
}
else //有泄漏返回地址,无则返回null
return (int)( head.next? head.next->address :0 );
return 0;
}
///内存分配//
void *MLCmalloc(size_t size)
{
void *pMalc=malloc(size);
if(pMalc==NULL)
return NULL;
else if(MemoryContrl((size_t)pMalc, _MC)==1)
{
free(pMalc); //动态链建立失败时释放此次分配的空间
return NULL;
}
else
return pMalc;
}
///内存释放//
void MLCfree(void *ptr)
{
if(MemoryContrl((size_t)ptr, _FE)==-1)
{
printf("%s/n","被释放的内存地址错误!");
return ;
}
else
free(ptr);
}
//检查泄漏//
size_t CheckLeak()
{
return (size_t)(MemoryContrl((size_t)0, _Check));
}
#include "mem.h"
int main()
{
char **p=NULL;
char *str="1234567890098765432";
char *tmp,i;
p=(char **)MLCmalloc(10*sizeof(char*));
printf("分配p=%#x/n",p);
for( i=0;i<10; i++)
{
p[i]=(char *)MLCmalloc(20*sizeof(char));
sscanf(str,"%s",p[i]);
}
for(i=0; i<10; i++)
printf("&p[%d]=%#x *p[%d]=%s/n",i,p[i],i,p[i]);
printf("释放p=%#x/n",p); //不安正常顺序释放
MLCfree(p);
while((tmp=(char*)CheckLeak())!=0) //检测是否有泄漏空间
{
MLCfree(tmp); //释放检测到的泄漏空间
printf("tmp=%#x/n",tmp);
}
return 0;
}