内存泄漏之malloc替换方法

时间:2021-07-13 04:56:08

//内存泄漏之malloc替换方法

//内存泄漏之malloc替换方法
#include "stdio.h"
#include "stdlib.h"

/*文件路径名长度,可以根据需要修改*/
#define patch_len 50
struct record
{
char name[patch_len+1];
unsigned int line;
unsigned int addr;
struct record *next;
};

#define Malloc(size) malloc_ext(size,__FUNCTION__, __LINE__)
#define Free(p) free_ext(p,__FUNCTION__, __LINE__)

void * malloc_ext(size_t size,const char *name, unsigned int line);
void free_ext(void * p,const char *name, unsigned int line);

struct record * add_record(struct record *head, unsigned int addr, unsigned int line, const char *name);
int delete_record(struct record *head, unsigned int addr);
void show_record(void);

/*定义未释放内存链表头节点*/
struct record * record_list = NULL;

struct record * add_record(struct record *head, unsigned int addr, unsigned int line, const char *name)
{
struct record *m = NULL;
struct record *n = NULL;
if(head == NULL)
{
head = (struct record*)malloc(sizeof(struct record));
head->addr = addr;
head->line = line;
memcpy(head->name, name, patch_len);
head->name[patch_len] = '\0';
head->next = NULL;
return head;
}
m = head;
while(m->next != NULL)
{
m = m->next;
}

n = (struct record*)malloc(sizeof(struct record));
n->addr = addr;
n->line = line;
memcpy(n->name, name, patch_len);
n->name[patch_len] = '\0';
n->next = NULL;
m->next = n;
m = n;
return head;
}
int delete_record(struct record *head, unsigned int addr)
{
struct record *m = NULL;
struct record *n = NULL;

if(head == NULL)
{
printf("warning: have been freed before!!");
}
m = n = head;
if(head->next == NULL)
{
if(n->addr == addr)
{
free(head);
record_list = head = NULL;
}
return 1;
}
n = m->next;
while(n != NULL)
{
if(n->addr == addr)
{
m->next = n->next;
free(n);
return 1;
}
m = m->next;
n = n->next;
}
return 1;
}

void * malloc_ext(size_t size,const char *name,unsigned int line)
{
void *p = NULL;

p = malloc(size);
if(p != NULL)
{
record_list = add_record(record_list, (unsigned int)p, line, name);
}
return p;
}

void free_ext(void * p,const char *name, unsigned int line)
{
if (p == NULL)
{
printf("can\'t free a null pointer\n");
return;
}
delete_record(record_list, (unsigned int)p);
free(p);
}

/*根据各自的系统打印未释放内存链表内容,或者写入文件*/
void show_record(void)
{
struct record *p = NULL;
struct record *head = NULL;
int i = 0;

head = record_list;
if(head == NULL)
{
printf("list is enpty!\n");
return;
}
p = head;

printf("memory list without free:\n");
while(p != NULL)
{
printf("<%s,%u>Node is:%d ,addr = 0x%x\n",p->name,p->line,++i,p->addr);

p = p->next;
}
}

char *getmem(char *string,int len)
{
char *buf = NULL;

//malloc_stats();

buf = Malloc(len);
memset(buf , 0 ,len);
snprintf(buf,len,"%s",string);
Free(buf);

//malloc_stats();
return buf;
}

int main(int argc ,char *argv[])
{
int i = 0;
char welcome[64] = "hello,world!";
printf("test malloc start:\n");
for(i = 0;i<10;i++)
{
getmem(welcome,sizeof(welcome));
}
show_record();
printf("test over.\n");

return;
}