Leak detector

Head file:

leak.h:
#ifndef  LEAK_DETECTOR_C_H
#define  LEAK_DETECTOR_C_H

#define  FILE_NAME_LENGTH       256
#define  OUTPUT_FILE      "/home/leak_info.txt"
#define  malloc(size)           xmalloc (size, __FILE__, __LINE__)
#define  calloc(elements, size)   xcalloc (elements, size, __FILE__, __LINE__)
#define  free(mem_ref)        xfree(mem_ref)

struct _MEM_INFO
{
 void   *address;
 unsigned int size;
 char   file_name[FILE_NAME_LENGTH];
 unsigned int line;
};
typedef struct _MEM_INFO MEM_INFO;

struct _MEM_LEAK {
 MEM_INFO mem_info;
 struct _MEM_LEAK * next;
};
typedef struct _MEM_LEAK MEM_LEAK;

void add(MEM_INFO alloc_info);
void erase(unsigned pos);
void clear(void);

void * xmalloc(unsigned int size, const char * file, unsigned int line);
void * xcalloc(unsigned int elements, unsigned int size, const char * file, unsigned int line);
void xfree(void * mem_ref);

void add_mem_info (void * mem_ref, unsigned int size,  const char * file, unsigned int line);
void remove_mem_info (void * mem_ref);
void report_mem_leak(void);

#endif


Source file:
#include	<stdio.h>
#include <malloc.h>
#include <string.h>
#include "leak.h"

#undef malloc
#undef calloc
#undef  free


static MEM_LEAK * ptr_start = NULL;
static MEM_LEAK * ptr_next =  NULL;

/*
 * adds allocated memory info. into the list
 *
 */
void add(MEM_INFO alloc_info)
{

MEM_LEAK * mem_leak_info = NULL;
mem_leak_info = (MEM_LEAK *) malloc (sizeof(MEM_LEAK));
mem_leak_info->mem_info.address = alloc_info.address;
mem_leak_info->mem_info.size = alloc_info.size;
strcpy(mem_leak_info->mem_info.file_name, alloc_info.file_name); 
mem_leak_info->mem_info.line = alloc_info.line;
mem_leak_info->next = NULL;

if (ptr_start == NULL)
{
ptr_start = mem_leak_info;
ptr_next = ptr_start;
}
else {
ptr_next->next = mem_leak_info;
ptr_next = ptr_next->next;
}

}

/*
 * erases memory info. from the list
 *
 */
void erase(unsigned pos)
{

unsigned index = 0;
MEM_LEAK * alloc_info, * temp;

if(pos == 0)
{
MEM_LEAK * temp = ptr_start;
ptr_start = ptr_start->next;
free(temp);
}
else 
{
for(index = 0, alloc_info = ptr_start; index < pos; 
alloc_info = alloc_info->next, ++index)
{
if(pos == index + 1)
{
temp = alloc_info->next;
alloc_info->next =  temp->next;
free(temp);
break;
}
}
}
}

/*
 * deletes all the elements from the list
 */
void clear()
{
MEM_LEAK * temp = ptr_start;
MEM_LEAK * alloc_info = ptr_start;

while(alloc_info != NULL) 
{
alloc_info = alloc_info->next;
free(temp);
temp = alloc_info;
}
}

/*
 * replacement of malloc
 */
void * xmalloc (unsigned int size, const char * file, unsigned int line)
{
void * ptr = malloc (size);
if (ptr != NULL) 
{
add_mem_info(ptr, size, file, line);
}
return ptr;
}

/*
 * replacement of calloc
 */
void * xcalloc (unsigned int elements, unsigned int size, const char * file, unsigned int line)
{
unsigned total_size;
void * ptr = calloc(elements , size);
if(ptr != NULL)
{
total_size = elements * size;
add_mem_info (ptr, total_size, file, line);
}
return ptr;
}


/*
 * replacement of free
 */
void xfree(void * mem_ref)
{
remove_mem_info(mem_ref);
free(mem_ref);
}

/*
 * gets the allocated memory info and adds it to a list
 *
 */
void add_mem_info (void * mem_ref, unsigned int size,  const char * file, unsigned int line)
{
MEM_INFO mem_alloc_info;

/* fill up the structure with all info */
memset( &mem_alloc_info, 0, sizeof ( mem_alloc_info ) );
mem_alloc_info.address  = mem_ref;
mem_alloc_info.size = size;
strncpy(mem_alloc_info.file_name, file, FILE_NAME_LENGTH);
mem_alloc_info.line = line;

/* add the above info to a list */
add(mem_alloc_info);
}

/*
 * if the allocated memory info is part of the list, removes it
 *
 */
void remove_mem_info (void * mem_ref)
{
unsigned short index;
MEM_LEAK  * leak_info = ptr_start;

/* check if allocate memory is in our list */
for(index = 0; leak_info != NULL; ++index, leak_info = leak_info->next)
{
if ( leak_info->mem_info.address == mem_ref )
{
erase ( index );
break;
}
}
}

/*
 * writes all info of the unallocated memory into a file
 */
void report_mem_leak(void)
{
unsigned short index;
MEM_LEAK * leak_info;

FILE * fp_write = fopen (OUTPUT_FILE, "wt");
char info[1024];

if(fp_write != NULL)
{
sprintf(info, "%s\n""Memory Leak Summary");
fwrite(info, (strlen(info) + 1) , 1, fp_write);
sprintf(info, "%s\n""-----------------------------------");
fwrite(info, (strlen(info) + 1) , 1, fp_write);

for(leak_info = ptr_start; leak_info != NULL; leak_info = leak_info->next)
{
sprintf(info, "address : %d\n", leak_info->mem_info.address);
fwrite(info, (strlen(info) + 1) , 1, fp_write);
sprintf(info, "size    : %d bytes\n", leak_info->mem_info.size);
fwrite(info, (strlen(info) + 1) , 1, fp_write);
sprintf(info, "file    : %s\n", leak_info->mem_info.file_name);
fwrite(info, (strlen(info) + 1) , 1, fp_write);
sprintf(info, "line    : %d\n", leak_info->mem_info.line);
fwrite(info, (strlen(info) + 1) , 1, fp_write);
sprintf(info, "%s\n""-----------------------------------");
fwrite(info, (strlen(info) + 1) , 1, fp_write);
}
}
clear();
}

Test file:

#include <malloc.h>
#include    <stdio.h>
#include    <stdlib.h>
#include "leak.h"
int main()
{
 char * ptr1 = (char *)malloc(10);
 int * ptr2 = (int *)calloc(10, sizeof(int));
 float * ptr3 = (float *) calloc(15, sizeof(float));
 free(ptr2);
 atexit(report_mem_leak);
 return 0;
}

posted on 2011-02-17 20:28 Enki 阅读(267) 评论(0)  编辑 收藏 引用


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理


<2024年4月>
31123456
78910111213
14151617181920
21222324252627
2829301234
567891011

导航

统计

常用链接

留言簿

随笔档案

文章档案

搜索

最新评论

阅读排行榜

评论排行榜