You can download all programs as a single tar.gz file from Download mychar . To get this file, in the web-browser, save this file as 'Text' type.
//***************************************************************** // Copyright policy is GNU/GPL but additional restriction is // that you include author's name and email on all copies // Author : Al Dev Email: 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); }