Download mychar ¿¡¼ ¸ðµç ÇÁ·Î±×·¥µéÀ» ÇϳªÀÇ tar.gz ÈÀÏ·Î ´Ù¿î·Îµå¹ÞÀ» ¼ö ÀÖ´Ù. ÀÌ ÈÀÏÀ» ¹ÞÀ¸·Á¸é À¥ºê¶ó¿ìÀú¿¡¼ ÀÌ ÈÀÏÀ» 'Text' ŸÀÔÀ¸·Î ÀúÀåÇÑ´Ù.
//*****************************************************************
//ÀúÀÛ±ÇÀº GNU/GPL ¿¡ ÀÖÁö¸¸ ÀúÀÚÀÇ À̸§°ú À̸ÞÀÏÀº ¸ðµç º¹»çº»¿¡
//Æ÷ÇÔ½ÃÄÑ¾ß ÇÑ´Ù.
//ÀúÀÚ: Al Dev À̸ÞÀÏ: alavoor@yahoo.com
//*****************************************************************
/*
** In your main() function put these lines -
char p_name[1024];
sprintf(p_name, "PROGRAM_NAME=%s", argv[0]);
putenv(p_name);
print_total_memsize(); // in the beginning
......
......
print_total_memsize(); // in the end
*/
#include <stdio.h>
#include <alloc.h> // for c++ -- malloc, alloc etc...
#include <stdlib.h> // malloc, alloc..
#include <time.h> // strftime, localtime, ...
#include <list.h> // strftime, localtime, ... see file include/g++/stl_list.h
//#include <debug.h> // debug_("a", a); debug2_("a", a, true);
#include "my_malloc.h"
const short SAFE_MEM = 10;
const short DATE_MAX_SIZE = 200;
const short MALLOC = 1;
const short REALLOC = 2;
const short VOID_TYPE = 1;
const short CHAR_TYPE = 2;
const short SHORT_TYPE = 3;
const short INT_TYPE = 4;
const short LONG_TYPE = 5;
const short FLOAT_TYPE = 6;
const short DOUBLE_TYPE = 7;
const char LOG_FILE[30] = "memory_error.log";
// Uncomment this line to debug total mem size allocated...
//#define DEBUG_MEM "debug_memory_sizes_allocated"
static void raise_error_exit(short mtype, short datatype, char fname[], int lineno);
#ifdef DEBUG
class MemCheck
{
public:
MemCheck(void *aptr, size_t amem_size, char fname[], int lineno);
void *ptr;
size_t mem_size;
static list<MemCheck> mcH; // list head
static unsigned long total_memsize; // total memory allocated
};
// Global variables ....
list<MemCheck> MemCheck::mcH;
unsigned long MemCheck::total_memsize = 0;
MemCheck::MemCheck(void *aptr, size_t amem_size, char fname[], int lineno)
{
char func_name[100];
FILE *ferr = NULL;
sprintf(func_name, "MemCheck() - File: %s Line: %d", fname, lineno);
ferr = fopen(LOG_FILE, "a");
if (ferr == NULL)
{
fprintf(stdout, "\nWarning: Cannot open file %s\n", LOG_FILE);
fprintf(stderr, "\nWarning: Cannot open file %s\n", LOG_FILE);
#ifdef DEBUG_MEM
exit(-1);
#else
return;
#endif
}
// Search if the pointer already exists in the list...
bool does_exist = false;
list<MemCheck>::iterator iter1; // see file include/g++/stl_list.h
//fprintf(ferr, "\n%s Before checking.. !!\n", func_name);
if (MemCheck::mcH.empty() == true )
{
//fprintf(ferr, "\n%s List is empty!!\n", func_name);
}
for (iter1 = MemCheck::mcH.begin(); iter1 != MemCheck::mcH.end(); iter1++)
{
if (iter1 == NULL)
{
fprintf(ferr, "\n%s Iterator iter1 is NULL!!\n", func_name);
break;
}
if ( ((*iter1).ptr) == aptr)
{
does_exist = true;
fprintf(ferr, "\n%s Already exists!!\n", func_name);
fprintf(ferr, "\n%s Fatal Error exiting now ....!!\n", func_name);
#ifdef DEBUG_MEM
exit(-1); //------------------------------------------------------------------>>>
#else
return;
#endif
// Now change the mem size to new values...
// For total size - Remove old size and add new size
//fprintf(ferr, "\n%s total_memsize = %lu\n", func_name, (*iter1).total_memsize);
//fprintf(ferr, "\n%s mem_size = %u\n", func_name, (*iter1).mem_size);
//fprintf(ferr, "\n%s amem_size = %u\n", func_name, amem_size);
(*iter1).total_memsize = (*iter1).total_memsize + amem_size;
if ((*iter1).total_memsize > 0 )
{
if ((*iter1).total_memsize >= (*iter1).mem_size )
(*iter1).total_memsize = (*iter1).total_memsize - (*iter1).mem_size;
else
{
fprintf(ferr, "\n\n%s total_memsize is less than mem_size!!", func_name);
fprintf(ferr, "\n%s total_memsize = %lu", func_name, (*iter1).total_memsize);
fprintf(ferr, "\n%s mem_size = %u", func_name, (*iter1).mem_size);
fprintf(ferr, "\n%s amem_size = %u\n", func_name, amem_size);
}
}
(*iter1).mem_size = amem_size;
}
}
// The pointer aptr does not exist in the list, so append it now...
if (does_exist == false)
{
//fprintf(ferr, "\n%s aptr Not found\n", func_name);
ptr = aptr;
mem_size = amem_size;
MemCheck::total_memsize += amem_size;
MemCheck::mcH.insert(MemCheck::mcH.end(), *this);
}
fclose(ferr);
}
static inline void call_check(void *aa, size_t tmpii, char fname[], int lineno)
{
MemCheck bb(aa, tmpii, fname, lineno);
if (& bb); // a dummy statement to avoid compiler warning msg.
}
static inline void remove_ptr(void *aa, char fname[], int lineno)
{
char func_name[100];
if (aa == NULL)
return;
sprintf(func_name, "remove_ptr() - File: %s Line: %d", fname, lineno);
FILE *ferr = NULL;
ferr = fopen(LOG_FILE, "a");
if (ferr == NULL)
{
fprintf(stdout, "\nWarning: Cannot open file %s\n", LOG_FILE);
fprintf(stderr, "\nWarning: Cannot open file %s\n", LOG_FILE);
#ifdef DEBUG_MEM
exit(-1);
#else
return;
#endif
}
bool does_exist = false;
if (MemCheck::mcH.empty() == true)
{
//fprintf(ferr, "\n%s List is empty!!\n", func_name);
//fclose(ferr);
//return;
}
list<MemCheck>::iterator iter1; // see file include/g++/stl_list.h
for (iter1 = MemCheck::mcH.begin(); iter1 != MemCheck::mcH.end(); iter1++)
{
if (iter1 == NULL)
{
fprintf(ferr, "\n%s Iterator iter1 is NULL!!\n", func_name);
break;
}
if ( ((*iter1).ptr) == aa)
{
does_exist = true;
// Now change the mem size to new values...
// For total size - Remove old size
//fprintf(ferr, "\n%s total_memsize = %lu\n", func_name, (*iter1).total_memsize);
//fprintf(ferr, "\n%s mem_size = %u\n", func_name, (*iter1).mem_size);
if ((*iter1).total_memsize > 0 )
{
if ((*iter1).total_memsize >= (*iter1).mem_size )
(*iter1).total_memsize = (*iter1).total_memsize - (*iter1).mem_size;
else
{
fprintf(ferr, "\n\n%s total_memsize is less than mem_size!!", func_name);
fprintf(ferr, "\n%s total_memsize = %lu", func_name, (*iter1).total_memsize);
fprintf(ferr, "\n%s mem_size = %u\n", func_name, (*iter1).mem_size);
}
}
MemCheck::mcH.erase(iter1);
break; // must break to avoid infinite looping
}
}
if (does_exist == false)
{
//fprintf(ferr, "\n%s Fatal Error: - You did not allocate memory!! \n", func_name);
//fprintf(ferr, "\n%s The value passed is %s\n", func_name, (char *) aa);
}
else
//fprintf(ferr, "\n%s found\n", func_name);
fclose(ferr);
}
static inline void call_free_check(void *aa, char *fname, int lineno)
{
char func_name[100];
sprintf(func_name, "call_free_check() - File: %s Line: %d", fname, lineno);
FILE *ferr = NULL;
ferr = fopen(LOG_FILE, "a");
if (ferr == NULL)
{
fprintf(stdout, "\nWarning: Cannot open file %s\n", LOG_FILE);
fprintf(stderr, "\nWarning: Cannot open file %s\n", LOG_FILE);
#ifdef DEBUG_MEM
exit(-1);
#else
return;
#endif
}
bool does_exist = false;
list<MemCheck>::iterator iter1; // see file include/g++/stl_list.h
for (iter1 = MemCheck::mcH.begin(); iter1 != MemCheck::mcH.end(); iter1++)
{
if (iter1 == NULL)
{
fprintf(ferr, "\n%s Iterator iter1 is NULL!!\n", func_name);
break;
}
if ( ((*iter1).ptr) == aa)
{
does_exist = true;
//fprintf(ferr, "\n%s iter1.mem_size = %u\n", func_name, (*iter1).mem_size);
//fprintf(ferr, "\n%s Total memory allocated = %lu\n", func_name, (*iter1).total_memsize);
if ((*iter1).total_memsize > 0 )
{
if ((*iter1).total_memsize >= (*iter1).mem_size )
(*iter1).total_memsize = (*iter1).total_memsize - (*iter1).mem_size;
else
{
fprintf(ferr, "\n\n%s total_memsize is less than mem_size!!", func_name);
fprintf(ferr, "\n%s total_memsize = %lu", func_name, (*iter1).total_memsize);
fprintf(ferr, "\n%s mem_size = %u", func_name, (*iter1).mem_size);
}
}
MemCheck::mcH.erase(iter1);
break; // must break to avoid infinite looping
}
}
if (does_exist == false)
{
fprintf(ferr, "\n%s Fatal Error: free() - You did not allocate memory!!\n",
func_name);
//fprintf(ferr, "\n%s The value passed is %s\n", func_name, (char *) aa);
fclose(ferr);
#ifdef DEBUG_MEM
exit(-1);
#else
return;
#endif
}
else
{
//fprintf(ferr, "\n%s found\n", func_name);
}
fclose(ferr);
}
void local_print_total_memsize(char *fname, int lineno)
{
char func_name[100];
sprintf(func_name, "local_print_total_memsize() - %s Line: %d", fname, lineno);
FILE *ferr = NULL;
ferr = fopen(LOG_FILE, "a");
if (ferr == NULL)
{
fprintf(stdout, "\nWarning: Cannot open file %s\n", LOG_FILE);
fprintf(stderr, "\nWarning: Cannot open file %s\n", LOG_FILE);
#ifdef DEBUG_MEM
exit(-1);
#else
return;
#endif
}
fprintf(ferr, "\n%s Total memory MemCheck::total_memsize = %lu\n", func_name, MemCheck::total_memsize);
fclose(ferr);
}
#else //------------> DEBUG
void local_print_total_memsize(char *fname, int lineno)
{
// This function is available whether debug or no-debug...
}
#endif // DEBUG
void local_my_free(void *aa, char fname[], int lineno)
{
if (aa == NULL)
return;
call_free_check(aa, fname, lineno);
free(aa);
aa = NULL;
}
// size_t is type-defed unsigned long
void *local_my_malloc(size_t size, char fname[], int lineno)
{
size_t tmpii = size + SAFE_MEM;
void *aa = NULL;
aa = (void *) malloc(tmpii);
if (aa == NULL)
raise_error_exit(MALLOC, VOID_TYPE, fname, lineno);
memset(aa, 0, tmpii);
call_check(aa, tmpii, fname, lineno);
return aa;
}
// size_t is type-defed unsigned long
char *local_my_realloc(char *aa, size_t size, char fname[], int lineno)
{
remove_ptr(aa, fname, lineno);
unsigned long tmpjj = 0;
if (aa) // aa != NULL
tmpjj = strlen(aa);
unsigned long tmpqq = size + SAFE_MEM;
size_t tmpii = sizeof (char) * (tmpqq);
aa = (char *) realloc(aa, tmpii);
if (aa == NULL)
raise_error_exit(REALLOC, CHAR_TYPE, fname, lineno);
// do not memset!! memset(aa, 0, tmpii);
aa[tmpqq-1] = 0;
unsigned long kk = tmpjj;
if (tmpjj > tmpqq)
kk = tmpqq;
for ( ; kk < tmpqq; kk++)
aa[kk] = 0;
call_check(aa, tmpii, fname, lineno);
return aa;
}
// size_t is type-defed unsigned long
short *local_my_realloc(short *aa, size_t size, char fname[], int lineno)
{
remove_ptr(aa, fname, lineno);
unsigned long tmpqq = size + SAFE_MEM;
size_t tmpii = sizeof (short) * (tmpqq);
aa = (short *) realloc(aa, tmpii);
if (aa == NULL)
raise_error_exit(REALLOC, CHAR_TYPE, fname, lineno);
// do not memset!! memset(aa, 0, tmpii);
// Not for numbers!! aa[tmpqq-1] = 0;
call_check(aa, tmpii, fname, lineno);
return aa;
}
// size_t is type-defed unsigned long
int *local_my_realloc(int *aa, size_t size, char fname[], int lineno)
{
remove_ptr(aa, fname, lineno);
unsigned long tmpqq = size + SAFE_MEM;
size_t tmpii = sizeof (int) * (tmpqq);
aa = (int *) realloc(aa, tmpii);
if (aa == NULL)
raise_error_exit(REALLOC, CHAR_TYPE, fname, lineno);
// do not memset!! memset(aa, 0, tmpii);
// Not for numbers!! aa[tmpqq-1] = 0;
call_check(aa, tmpii, fname, lineno);
return aa;
}
// size_t is type-defed unsigned long
long *local_my_realloc(long *aa, size_t size, char fname[], int lineno)
{
remove_ptr(aa, fname, lineno);
unsigned long tmpqq = size + SAFE_MEM;
size_t tmpii = sizeof (long) * (tmpqq);
aa = (long *) realloc(aa, tmpii);
if (aa == NULL)
raise_error_exit(REALLOC, CHAR_TYPE, fname, lineno);
// do not memset!! memset(aa, 0, tmpii);
// Not for numbers!! aa[tmpqq-1] = 0;
call_check(aa, tmpii, fname, lineno);
return aa;
}
// size_t is type-defed unsigned long
float *local_my_realloc(float *aa, size_t size, char fname[], int lineno)
{
remove_ptr(aa, fname, lineno);
unsigned long tmpqq = size + SAFE_MEM;
size_t tmpii = sizeof (float) * (tmpqq);
aa = (float *) realloc(aa, tmpii);
if (aa == NULL)
raise_error_exit(REALLOC, CHAR_TYPE, fname, lineno);
// do not memset!! memset(aa, 0, tmpii);
// Not for numbers!! aa[tmpqq-1] = 0;
call_check(aa, tmpii, fname, lineno);
return aa;
}
// size_t is type-defed unsigned long
double *local_my_realloc(double *aa, size_t size, char fname[], int lineno)
{
remove_ptr(aa, fname, lineno);
unsigned long tmpqq = size + SAFE_MEM;
size_t tmpii = sizeof (double) * (tmpqq);
aa = (double *) realloc(aa, tmpii);
if (aa == NULL)
raise_error_exit(REALLOC, CHAR_TYPE, fname, lineno);
// do not memset!! memset(aa, 0, tmpii);
// Not for numbers!! aa[tmpqq-1] = 0;
call_check(aa, tmpii, fname, lineno);
return aa;
}
static void raise_error_exit(short mtype, short datatype, char fname[], int lineno)
{
if (mtype == MALLOC)
{
fprintf(stdout, "\nFatal Error: malloc() failed!!");
fprintf(stderr, "\nFatal Error: malloc() failed!!");
}
else
if (mtype == REALLOC)
{
fprintf(stdout, "\nFatal Error: realloc() failed!!");
fprintf(stderr, "\nFatal Error: realloc() failed!!");
}
else
{
fprintf(stdout, "\nFatal Error: mtype not supplied!!");
fprintf(stderr, "\nFatal Error: mtype not supplied!!");
exit(-1);
}
// Get current date-time and print time stamp in error file...
char date_str[DATE_MAX_SIZE + SAFE_MEM];
time_t tt;
tt = time(NULL);
struct tm *ct = NULL;
ct = localtime(& tt); // time() in secs since Epoch 1 Jan 1970
if (ct == NULL)
{
fprintf(stdout, "\nWarning: Could not find the local time, localtime() failed\n");
fprintf(stderr, "\nWarning: Could not find the local time, localtime() failed\n");
}
else
strftime(date_str, DATE_MAX_SIZE , "%C", ct);
FILE *ferr = NULL;
char filename[100];
strcpy(filename, LOG_FILE);
ferr = fopen(filename, "a");
if (ferr == NULL)
{
fprintf(stdout, "\nWarning: Cannot open file %s\n", filename);
fprintf(stderr, "\nWarning: Cannot open file %s\n", filename);
}
else
{
// **************************************************
// ******* Do putenv in the main() function *********
// char p_name[1024];
// sprintf(p_name, "PROGRAM_NAME=%s", argv[0]);
// putenv(p_name);
// **************************************************
char program_name[200+SAFE_MEM];
if (getenv("PROGRAM_NAME") == NULL)
{
fprintf(ferr, "\n%sWarning: You did not putenv() PROGRAM_NAME env variable in main() function\n",
date_str);
program_name[0] = 0;
}
else
strncpy(program_name, getenv("PROGRAM_NAME"), 200);
if (mtype == MALLOC)
fprintf(ferr, "\n%s: %s - Fatal Error - my_malloc() failed.", date_str, program_name);
else
if (mtype == REALLOC)
{
fprintf(ferr, "\n%s: %s - Fatal Error - my_realloc() failed.", date_str, program_name);
char dtype[50];
switch(datatype)
{
case VOID_TYPE:
strcpy(dtype, "char*");
break;
case CHAR_TYPE:
strcpy(dtype, "char*");
break;
case SHORT_TYPE:
strcpy(dtype, "char*");
break;
case INT_TYPE:
strcpy(dtype, "char*");
break;
case LONG_TYPE:
strcpy(dtype, "char*");
break;
case FLOAT_TYPE:
strcpy(dtype, "char*");
break;
case DOUBLE_TYPE:
strcpy(dtype, "char*");
break;
default:
strcpy(dtype, "none*");
break;
}
fprintf(ferr, "\n%s %s - Fatal Error: %s realloc() failed!!", date_str, program_name, dtype);
}
fprintf(ferr, "\n%s %s - Very severe error condition. Exiting application now....",
date_str, program_name);
fclose(ferr);
}
exit(-1);
}