Page suivantePage précédenteTable des matières

17. Annexe D my_malloc.cpp

Vous pouvez récupérer tous les programmes en un seul tar.gz sur Telecharger String . Pour obtenir ce fichier, dans un butineur web, sauvez ce fichier en type 'texte'.


//*****************************************************************
// La licence de distribution est la GNU/GPL et vous devez inclure
// le nom et le mel de l'auteur dans toutes les copies
// Auteur : Al Dev    Mel : alavoor@yahoo.com
//*****************************************************************
#include <stdio.h>
#include <alloc.h>  // pour malloc, alloc etc...
#include <stdlib.h>  // malloc, alloc..
#include <time.h>  // strftime, localtime, ...
#include <list.h>  // strftime, localtime, ...  voir 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";
// Décommenter cette ligne pour déboguer la totalité de la mémoire allouée
//#define DEBUG_MEM  "debug_memory_sizes_allocated"
static void raise_error_exit(short mtype, short datatype, char fname[], int lineno);
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 est défini comme un entier long non signé (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 est défini comme un entier long non signé (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);
 // ne pas utiliser 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 est défini comme un entier long non signé (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);
 // ne pas utiliser memset ! memset(aa, 0, tmpii);
 // pas pour les nombres ! aa[tmpqq-1] = 0;
 //call_check(aa, tmpii, fname, lineno);
 return aa;
}
// size_t est défini comme un entier long non signé (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);
 // ne pas utiliser memset ! memset(aa, 0, tmpii);
 // pas pour les nombres ! aa[tmpqq-1] = 0;
 //call_check(aa, tmpii, fname, lineno);
 return aa;
}
// size_t est défini comme un entier long non signé (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);
 // ne pas utiliser memset ! memset(aa, 0, tmpii);
 // pas pour les nombres ! aa[tmpqq-1] = 0;
 //call_check(aa, tmpii, fname, lineno);
 return aa;
}
// size_t est défini comme un entier long non signé (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);
 // ne pas utiliser memset ! memset(aa, 0, tmpii);
 // pas pour les nombres ! aa[tmpqq-1] = 0;
 //call_check(aa, tmpii, fname, lineno);
 return aa;
}
// size_t est défini comme un entier long non signé (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);
 // ne pas utiliser memset ! memset(aa, 0, tmpii);
 // pas pour les nombres ! 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);
 }
 // Récupère la date et l'heure courantes et les met dans le fichier d'erreurs...
 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
 {
 // **************************************************
 // **** Fait le putenv dans la fonction main()  *****
 //              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);
}
// /////////////////////////////////////////////////////////////
//              Fonctions pour afficher la mémoire totale utilisée
//              Ces fonctions peuvent être utilisées pour déboguer
//              Devraient être commentées pour le code de production
// Utilisation de ces fonctions :
//              Dans votre fonction main(), mettre les lignes
//                      char p_name[1024];
//                      sprintf(p_name, "PROGRAM_NAME=%s", argv[0]);
//                      putenv(p_name);
//                      print_total_memsize(); // au debut
//                      ......
//                      ......
//                      print_total_memsize(); // à la fin
// /////////////////////////////////////////////////////////////
// *********************************************************
// ** Les fonctions ci-dessus utilisent le conteneur list de la STL.
// ** Pour plus d'aide sur les listes, voir
// **   http://www.sgi.com/Technology/STL and List.html
// **   http://www.sgi.com/Technology/STL and other_resources.html
// **   http://www.halpernwightsoftware.com/stdlib-scratch/quickref.html
// *********************************************************
/*
#ifndef DEBUG
void local_print_total_memsize(char *fname, int lineno)
{
 // Cette fonction est disponible dans les 2 modes débogage ou non-débogage...
}
#endif  //------------> si DEBUG n'est pas défini
#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;  // tete de la liste
 static  unsigned long           total_memsize;  // memore totale allouee
};
// Variables globales
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
 }
 // Cherche si le pointeur existe déjà dans la liste...
 bool does_exist = false;
 list<MemCheck>::iterator iter1; // voir include/g++/stl_list.h
 //fprintf(ferr, "\n%s Before checking.. !!\n", func_name);
 list<MemCheck>::size_type sztype; // voir include/g++/stl_list.h
 // Le pointeur aptr n'existe pas dans la liste, alors on l'ajoute...
 //if (MemCheck::mcH.size() == 0)
 if (sztype == 0)
 {
 //fprintf(ferr, "\n%s aptr Not found\n", func_name);
 ptr = aptr;
 mem_size = amem_size;
 MemCheck::total_memsize += amem_size;
 // Voir aussi push_front(), list(), list(n), list(n, T)
 MemCheck tmpck = *this;
 MemCheck::mcH.push_back(tmpck);
 //MemCheck::mcH.insert(MemCheck::mcH.begin(), tmpck);
 //MemCheck::mcH.insert(MemCheck::mcH.end(), *this);
 fprintf(ferr, "\n%s sztype is %d\n", func_name, sztype);
 return;
 }
 if (MemCheck::mcH.empty() ) //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
 // Change la taille de la mémoire pour de nouvelles valeurs
 // Pour la taille totale - supprimer l'ancienne taille et ajouter la nouvelle
 //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;
 }
 }
 // Le pointeur aptr n'existe pas dans la liste, alors on l'ajoute maintenant
 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);  // une instruction inutile pour éviter un avertissement du compilateur
}
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;
 // Change la taille de la mémoire pour les nouvelles valeurs
 // Pour la taille totale - supprimer l'ancienne taille
 //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;  // break pour éviter une boucle infinie
 }
 }
 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; // voir 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;  // break pour éviter une boucle infinie
 }
 }
 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);
}
#endif  //------------> si DEBUG est défini
*/


Page suivantePage précédenteTable des matières