#include #include #include // il s'agit de fournir un système d'allocation plus sûr que le module // standard pour augmenter nos chances de détection d'erreur on met en // oeuvre les principes suivants : // // 1 les fonctions retournent toujours la quantité de mémoire demandée // // 2 le nombre d'allocations et de liberations est mémorisé // // 3 la fonction free essaye de vérifier la qualité de son paramètre // grâce à un tatouage // static const long NOMBRE_MAGIQUE = 0xABCD5678; static unsigned long nb_alloc = 0; static unsigned long nb_free = 0; static unsigned long nb_move = 0; unsigned long mem_nb_alloc () { return nb_alloc; } unsigned long mem_nb_free () { return nb_free; } unsigned long mem_nb_move () { return nb_move; } void * mem_calloc (size_t nmemb, size_t size) { long *tmp; assert (size != 0); if (nmemb == 0) return NULL; tmp = calloc (nmemb * size + sizeof (NOMBRE_MAGIQUE), 1); assert (tmp != NULL); *tmp = NOMBRE_MAGIQUE; nb_alloc++; return (void *) (tmp + 1); } void * mem_malloc (size_t size) { long *tmp; if (size == 0) return NULL; tmp = (long *) malloc (size + sizeof (NOMBRE_MAGIQUE)); assert (tmp != NULL); *tmp = NOMBRE_MAGIQUE; nb_alloc++; return (void *) (tmp + 1); } void mem_free (void *ptr) { long *tmp = ((long *) ptr) - 1; assert (*tmp == NOMBRE_MAGIQUE); *tmp = 0; free (tmp); nb_free++; } void * mem_realloc (void *ptr, size_t size) { if (ptr == NULL) return mem_malloc (size); if (size == 0) { mem_free (ptr); return NULL; } { long *old = ((long *) ptr) - 1; long *new; assert (*old == NOMBRE_MAGIQUE); *old = 0; new = realloc (old, size + sizeof (NOMBRE_MAGIQUE)); if (new != old) { nb_move++; } *new = NOMBRE_MAGIQUE; return (void *) (new + 1); } }