用单链表实现的内存管理

用单链表实现的内存管理
   
   在C语言论坛中看了dgarc发表的一个贴子后,按要求写了一段代码,可以实现内存分配的管理,避免内存泄漏,欢迎各位测试,如遇bug,敬请指出,我将进行有针对性的改进,然后重新贴出来。

要求如下

    题目:监控应用程序的内存申请和释放 
    描述:
         不考虑多线程,使用动态单链表的方式进行操作,在应用程序申请内存时,需要把该内存节点信息插入链表进行记录,应用程序释放内存,把相应内存节点的信息从 链表中删除,在应用程序退出时,如果链表仍然存在节点,说明存在内存泄露,应用程序不存在内存泄露,则链表为空。
MLCmalloc()  封装了malloc ,同时将信息插入链表操作
MLCfree()    封装了free ,同时将信息从链表中删除

程序代码:
    下列代码在满足题目要求的同时,增加了对泄漏空间的检测和释放功能。
  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <windows.h>

  4. #define   _MC    1     // MLCmalloc()的标志
  5. #define   _FE    0     // MLCfree()的标志
  6. #define  _Check  -1    //检测内存的标志


  7. typedef struct _Memory         //单向链表结构
  8. {
  9.     unsigned int address;
  10.     struct _Memory *next;
  11. }Mem, *LinkMem;




  1.  ///内存管理//
  2. int MemoryContrl(size_t addr,char flag) 
  3. {
  4.     static Mem head;        //保存链表头     
  5.     LinkMem tmp=head.next, node=&head ; 
  6.     if( _MC==flag )         //增加链表节点
  7.     {
  8.         while(tmp)              
  9.         {
  10.             node=tmp;
  11.             tmp=tmp->next;
  12.         }
  13.         node->next=(LinkMem)malloc(sizeof(Mem));
  14.         if(node->next==NULL)
  15.             return 1;   //分配失败!
  16.         node=node->next;
  17.         node->address=addr;
  18.         node->next=NULL;
  19.     }
  20.     else if( _FE==flag)     //删除节点
  21.     {
  22.         while(tmp && (tmp->address!=addr))
  23.         {
  24.             node=tmp;
  25.             tmp=tmp->next;
  26.         }
  27.         if(tmp==NULL)
  28.             return -1;  //free地址出错!
  29.         else
  30.         {
  31.             node->next=tmp->next;
  32.             free(tmp);
  33.         }
  34.     }
  35.     else                           //有泄漏返回地址,无则返回null
  36.         return (int)( head.next? head.next->address :0 );  
  37.     return 0;
  38. }

  39.  ///内存分配//

  40. void *MLCmalloc(size_t size)  
  41. {
  42.     void *pMalc=malloc(size);
  43.     if(pMalc==NULL)
  44.         return NULL;
  45.     else if(MemoryContrl((size_t)pMalc, _MC)==1)
  46.     {
  47.         free(pMalc);   //动态链建立失败时释放此次分配的空间
  48.         return NULL;
  49.     }       
  50.     else
  51.         return pMalc;
  52. }

  1. ///内存释放//

  1. void MLCfree(void *ptr)       
  2. {
  3.     if(MemoryContrl((size_t)ptr, _FE)==-1)
  4.     {
  5.         printf("%s/n","被释放的内存地址错误!");
  6.         return ;
  7.     }
  8.     else
  9.         free(ptr);
  10. }


  1. //检查泄漏//
  2. size_t CheckLeak()  
  3. {
  4.     return (size_t)(MemoryContrl((size_t)0, _Check));
  5. }

  6. int main()
  7. {
  8.     char **p=NULL;
  9.     char *str="1234567890098765432";
  10.     char *tmp,i;
  11.     p=(char **)MLCmalloc(10*sizeof(char*));
  12.     printf("分配p=%#x/n",p);
  13.     for( i=0;i<10; i++)
  14.     {
  15.         p[i]=(char *)MLCmalloc(20*sizeof(char));
  16.         sscanf(str,"%s",p[i]);
  17.     }
  18.     for(i=0; i<10; i++)
  19.         printf("&p[%d]=%#x  *p[%d]=%s/n",i,p[i],i,p[i]);
  20.     printf("释放p=%#x/n",p);   //不安正常顺序释放
  21.     MLCfree(p);
  22.     while((tmp=(char*)CheckLeak())!=0)  //检测是否有泄漏空间
  23.     {
  24.         MLCfree(tmp);               //释放检测到的泄漏空间
  25.         printf("tmp=%#x/n",tmp);
  26.     }
  27.     return 0;

  28. }
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值