用单链表实现的内存管理
在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));
- }
- 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;
- }