初窥内存管理(二)

     发现两篇内存池的博文,博文地址如下,写的很好,能避免内存碎片和内存泄露问题,比我这个玩具代码要好很多,大家可以看看:

http://www.cnblogs.com/bangerlee/archive/2011/08/31/2161421.html

http://blog.csdn.net/060/article/details/1326025


    在我们做项目的时候,经常会分配了内存,然后却忘了释放,造成内存泄漏的问题。

    以下代码可以实现在代码退出的时候自动释放之前申请但未释放的内存。

    其原理是:用一个双向链表维护申请的内存块,申请内存则插入对应节点,释放则删除相应节点;当程序退出的时候,遍历双向链表,释放内存,清空双向链表。

    代码如下:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

struct Node
{
 struct Node *preNode;//前一个节点
 struct Node *nextNode;//后一个节点
 void **varAddr;//存储指针变量的地址
 int size;
 char freed;
};

struct Chain
{
 struct Node *first;
 struct Node *last;
 int size;
};
void InitChain();
struct Node* InitNode(struct Node *pn);
int Push(struct Node *pn);
int RemoveChain(void **id);
int FreeChain();


void* MyMalloc(void **p,int size);
void* MyCalloc(void **p,int nsize,int usize);
void* MyRealloc(void **p,int size);
void MyFree(void **p);

static struct Chain chain;//定义一个链表的静态变量


/*初始化链表*/
void InitChain()
{
 chain.first=NULL;
 chain.last=NULL;
 chain.size=0;
}
/*初始化一个链表上的节点*/
struct Node* InitNode(struct Node *pn)
{
 pn=(struct Node *)malloc(sizeof(struct Node));
 if(pn==NULL)
  return NULL;
 pn->preNode=NULL;
 pn->nextNode=NULL;
 pn->freed=0;
 pn->varAddr=0;
 pn->size=0;
 return pn;
}
/*加入一个新的内存分配的节点*/
int Push(struct Node *pn)
{
 struct Node *last=chain.last;
 struct Node *first=chain.first;
 if(first==NULL)
 {
  chain.first=pn;
  chain.last=pn;
 }
 else
 {
  chain.last->nextNode=pn;
  pn->preNode=chain.last;
  chain.last=pn;
 }
 chain.size++;
 return 1;
}
/*
从链表中移除一个节点
*/
int RemoveChain(void **id)
{
 struct Node *first=chain.first;
 struct Node *tp1=NULL,*tp2=NULL;
 if(first==NULL)
  return 0;
 while(first)
 {

  if((long)first->varAddr==(long)id)
  {
   tp1=first->preNode;
   tp2=first->nextNode;
   if(tp1)
   {
    if(tp2)
    {
     tp1->nextNode=tp2;
     tp2->preNode=tp1;
    }
    else
    {
     tp1->nextNode=NULL;
     chain.last=tp1;
    }
   }
   else
   {
    tp2->preNode=NULL;
    chain.first=tp2;
   }
   free(first);
   chain.size--;
   break;
  }
  first=first->nextNode;
 }
 return 1;
}
/*清空链表*/
int FreeChain()
{
 struct Node *first=chain.first;
 struct Node *tp1=NULL;
 while(first)
 {
  tp1=first->nextNode;
  free((void *)*(first->varAddr));
  free(first);
  first=tp1;
 }
 chain.first=NULL;
 chain.last=NULL;
 chain.size=0;
 return 1;
}
/*
自定义的malloc,calloc,realloc,free函数
void **p参数 是存储分配内存地址的变量的地址,根据这个地址与分配内存关联,进行管理
*/
void* MyMalloc(void **p,int size)
{
 struct Node *pn=NULL;
 (*p)=malloc(size);
 if(p==NULL)
  return NULL;
 pn=InitNode(pn);
 if(pn==NULL)
  return NULL;
 pn->varAddr=p;
 pn->size=size;
 Push(pn);
 return (*p);
}
void* MyCalloc(void **p,int nsize,int usize)
{
 struct Node *pn=NULL;
 (*p)=calloc(nsize,usize);
 if(p==NULL)
  return NULL;
 pn=InitNode(pn);
 if(pn==NULL)
  return NULL;
 pn->varAddr=p;
 pn->size=nsize*usize;
 Push(pn);
 return (*p);
}
void* MyRealloc(void **p,int size)
{
 struct Node *pn=NULL;
 (*p)=realloc((*p),size);
 if(p==NULL)
  return NULL;
 pn=InitNode(pn);
 if(pn==NULL)
  return NULL;
 pn->varAddr=p;
 pn->size=size;
 RemoveChain(p);
 Push(pn);
 return (*p);
}

void MyFree(void **p)
{
 if((*p)==NULL)
  return;
 free((*p));//释放内存
 RemoveChain(p);//把相关节点从链表移除
}


int main()
{
 char *p=NULL;
 char *p2=NULL;
 int *p3=NULL;
 InitChain();
 p=(char *)MyCalloc((void **)&p,100,sizeof(char));
 strcpy(p,"abcdefgh...");
 p2=(char *)MyMalloc((void **)&p2,18*sizeof(char));
 p3=(int *)MyMalloc((void **)&p3,10*sizeof(int));
 p3=(int *)MyRealloc((void **)&p3,20*sizeof(int));
 MyFree((void **)&p2);
 FreeChain();
 return 0;
}


评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值