I worked for a long time for this article. This program is tested on Sun-Solaris system using gcc compiler.
In market, there are a lot of tools for detecting the memory leaks. Here I made a program which has to include in your source file and it will tell the desired informations to find where memory leaks happen.
There are two files one is findLeak.c and other is findLeak.h . Source file is test.c , this is your program which you want to check memory leaks.
Concept is that when user call library function "malloc or calloc " for allocating dynamic memory, then we have to call our malloc or calloc (In case of my source code 'MyCalloc' function in place of 'calloc' and MyMalloc function in place of 'malloc'). So we have to define malloc to your malloc and in .c file you have to undef malloc and calloc By this way we can call our MyMalloc or MyCalloc function and in this function we will call another function which keeps all info about how much memory allocated. We will do the same for Library function "free" to deallocating memory( In my source file "MyFree" is used in plae of free function).
Now for keeping information, i made a simple singly linked list. which will add info about memory when user call "malloc" or "calloc" function and will also keep information when user call "free" function.
By program you can easily understand.
Heder File : findLeak.h
Code: c
#define uint unsigned int
#define cchar const char
#define OutFile "/home/asadulla/test/MemLeakInfo.txt" // Just Suppose
#define MAX_FILENAME_LENGTH 256
#define calloc(objs, nSize) MyCalloc (objs, nSize, __FILE__, __LINE__)
#define malloc(nSize) MyMalloc (nSize, __FILE__, __LINE__)
#define free(rMem) MyFree(rMem)
// This structure is keeping info about memory leak
struct InfoMem
{
//starting address of memory where pointer points
void *addr;
//Total size of memory in bytes which By malloc
//allocates memory dynamically */
uint nSize;
//Source File Name which you want
//to find memory leak information
char fileName[MAX_FILENAME_LENGTH];
//Line number of source File due to
// which User forget to deallocate memory
uint lineNumber;
};
typedef struct InfoMem infoMem;
//This is link list of InfoMem which keeps a List of memory Leak in a source file
struct LeakMem
{
infoMem memData;
struct LeakMem *nxt; // Next Memory leak Block
};
typedef struct LeakMem leakMem;
// This function is used for writing into file to see the memory leaks summary
void WriteMemLeak(void);
// These two function add information of memory leak information when user
// calls malloc or calloc
void SubAddMemInfo(void *rMem, uint nSize, cchar *file, uint lno);
void SubAdd(infoMem alloc_info);
// These two function remove and deallocated memory and remove the leak
// information when user calls free function
void ResetInfo(uint pos); //erase
void DeleteAll(void); //clear(void);
// This is hidden to user , This function will call when user call malloc function
void *MyMalloc(uint size, cchar *file, uint line);
// This is hidden to user , This function will call when user call calloc function
void *MyCalloc(uint elements, uint size, cchar * file, uint lno);
// This is hidden to user , This function will call when user call free function
void MyFree(void * mem_ref);
Source File: findLeak.c
Code: c
#include
#include
#include
#include "findLeak.h"
#undef malloc
#undef calloc
#undef free
static leakMem * ptr_start = NULL;
static leakMem * ptr_next = NULL;
// -----------------------------------------------------------
// Name: MyMalloc
// Desc: This is hidden to user. when user call malloc function then
// this function will be called.
void *MyMalloc (uint nSize, cchar* file, uint lineNumber)
{
void * ptr = malloc (nSize);
if (ptr != NULL)
{
SubAddMemInfo(ptr, nSize, file, lineNumber);
}
return ptr;
}
// -----------------------------------------------------------
// Name: MyCalloc
// Desc: This is hidden to user. when user call calloc function then
// this function will be called.
void * MyCalloc (uint elements, uint nSize, const char * file, uint lineNumber)
{
uint tSize;
void * ptr = calloc(elements , nSize);
if(ptr != NULL)
{
tSize = elements * nSize;
SubAddMemInfo (ptr, tSize, file, lineNumber);
}
return ptr;
}
// -----------------------------------------------------------
// Name: SubAdd
// Desc: It's actually Adding the Info.
void SubAdd(infoMem alloc_info)
{
leakMem * mem_leak_info = NULL;
mem_leak_info = (leakMem *) malloc (sizeof(leakMem));
mem_leak_info->memData.addr = alloc_info.addr;
mem_leak_info->memData.nSize = alloc_info.nSize;
strcpy(mem_leak_info->memData.fileName, alloc_info.fileName);
mem_leak_info->memData.lineNumber = alloc_info.lineNumber;
mem_leak_info->nxt = NULL;
if (ptr_start == NULL)
{
ptr_start = mem_leak_info;
ptr_next = ptr_start;
}
else {
ptr_next->nxt = mem_leak_info;
ptr_next = ptr_next->nxt;
}
}
// -----------------------------------------------------------
// Name: ResetInfo
// Desc: It erasing the memory using by List on the basis of info( pos)
void ResetInfo(uint pos)
{
uint index = 0;
leakMem * alloc_info, * temp;
if(pos == 0)
{
leakMem * temp = ptr_start;
ptr_start = ptr_start->nxt;
free(temp);
}
else
{
for(index = 0, alloc_info = ptr_start; index < pos;
alloc_info = alloc_info->nxt, ++index)
{
if(pos == index + 1)
{
temp = alloc_info->nxt;
alloc_info->nxt = temp->nxt;
free(temp);
break;
}
}
}
}
// -----------------------------------------------------------
// Name: DeleteAll
// Desc: It deletes the all elements which resides on List
void DeleteAll()
{
leakMem * temp = ptr_start;
leakMem * alloc_info = ptr_start;
while(alloc_info != NULL)
{
alloc_info = alloc_info->nxt;
free(temp);
temp = alloc_info;
}
}
// -----------------------------------------------------------
// Name: MyFree
// Desc:
void MyFree(void * mem_ref)
{
uint loop;
// if the allocated memory info is part of the list, removes it
leakMem *leak_info = ptr_start;
/* check if allocate memory is in our list */
for(loop = 0; leak_info != NULL; ++loop, leak_info = leak_info->nxt)
{
if ( leak_info->memData.addr == mem_ref )
{
ResetInfo(loop);
break;
}
}
free(mem_ref);
}
// -----------------------------------------------------------
// Name: SubAddMemInfo
// Desc: it also fill the the Info
void SubAddMemInfo (void * mem_ref, uint nSize, cchar * file, uint lineNumber)
{
infoMem AllocInfo;
/* fill up the structure with all info */
memset( &AllocInfo, 0, sizeof ( AllocInfo ) );
AllocInfo.addr = mem_ref;
AllocInfo.nSize = nSize;
strncpy(AllocInfo.fileName, file, MAX_FILENAME_LENGTH);
AllocInfo.lineNumber = lineNumber;
/* SubAdd the above info to a list */
SubAdd(AllocInfo);
}
// -----------------------------------------------------------
// Name: WriteMemLeak
// Desc: It writes information about Memory leaks in a file
// Example: File is as : "/home/asadulla/test/MemLeakInfo.txt"
void WriteMemLeak(void)
{
uint index;
leakMem *leak_info;
FILE * fp_write = fopen(OutFile, "wt");
char info[1024];
if(fp_write != NULL)
{
sprintf(info, "%s\n", "SUMMARY ABOUT MEMORY LEAKS OF YOUR SOURCE FILE ");
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->nxt)
{
sprintf(info, "Name of your Source File : %s\n", leak_info->memData.fileName);
fwrite(info, (strlen(info) + 1) , 1, fp_write);
sprintf(info, "Starting Address : %d\n", leak_info->memData.addr);
fwrite(info, (strlen(info) + 1) , 1, fp_write);
sprintf(info, " Total size Of memory Leak : %d bytes\n", leak_info->memData.nSize);
fwrite(info, (strlen(info) + 1) , 1, fp_write);
sprintf(info, "Line Number for which no DeAllocation : %d\n", leak_info->memData.lineNumber);
fwrite(info, (strlen(info) + 1) , 1, fp_write);
sprintf(info, "%s\n", "-----------------------------------");
fwrite(info, (strlen(info) + 1) , 1, fp_write);
fwrite(info, (strlen(info) + 1) , 1, fp_write);
}
}
DeleteAll();
}
Source File for detecting memory leak is as Here you can gice your own source file and in this source file you have write onle line to include file #include"findLeak.h"
Source File : test.c
Code: c
#include
#include"findLeak.h"
int main()
{
int *p1 = (int *)malloc(10);
int *p2 = (int *)calloc(10, sizeof(int));
char *p3 = (char *) calloc(15, sizeof(float));
float *p4 = (float*) malloc(16);
free(p2);
WriteMemLeak();
return 0;
}
Now user can compile these programmes in a console as :
> g++ test.c findLeak.c
and give a command for run
> ./a.out
then go to you your directory where you have defined a macro "OutFile" and open this defined file and you can see the results.
Output of above source file is as:
Code: output
SUMMARY ABOUT MEMORY LEAKS OF YOUR SOURCE FILE
-----------------------------------
Name of your Source File : test.c
Starting Address : 184960
Total size Of memory Leak : 10 bytes
Line Number for which no DeAllocation : 7
-----------------------------------
-----------------------------------
Name of your Source File : test.c
Starting Address : 187104
Total size Of memory Leak : 60 bytes
Line Number for which no DeAllocation : 9
-----------------------------------
-----------------------------------
Name of your Source File : test.c
Starting Address : 184984
Total size Of memory Leak : 16 bytes
Line Number for which no DeAllocation : 10
-----------------------------------
-----------------------------------
2 comments:
This article is very Important for me. Can i take it for my college for B.tech student. This example builds their concepts of memory leaks.
Thank you very much
If you have any doubts Or more clearify then mail me or post more comments. Or see
more my articles at
codeprojects.com
go4expert.com
etc...
Post a Comment