Dans la fonction xmalloc, pour le malloc de la ligne 15, il ne faudrait pas vérifier si la mémoire a bien été allouée ?
Un ramasse-miette, de l'anglais garbage collector, est un système de recyclage automatique de la mémoire. Il est souvent utilisé dans les programmes cycliques comme par exemple un shell.
Le C n'en implémente pas comme le langage python. C'est pourtant un outil très util et indispensable dans la plupart des cas.
Ici l'astuce consiste à créer des fonctions wrapper pour free et malloc. Une fois que tous nos appels d'allocation et de libération de mémoire passent par eux il est facile de créer une structure de type pile qui empile l'adresse de chaque allocation pour ensuite tout libérer d'un coup à la fin du cycle.
Pour la gestion de la pile nous allons utiliser les fonctions très pratique du header standard sys/queue.h, étant différent selon les OS je vous conseil de l'embarquer dans votre projet.
Tout d'abord définissons et initialisons la pile :
1 2 3 4 5 6 | typedef struct stack_s { void *adr; SLIST_ENTRY(stack_s) next; } stack_s; static SLIST_HEAD (, stack_s) mstack = SLIST_HEAD_INITIALIZER (&mstack); |
Il ne nous reste plus qu'a créer ensuite une fonction xmalloc() qui se chargera d'allouer la zone mémoire et d'empiler l'adresse sur notre pile :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | void *xmalloc (size_t size) { void *ret; stack_s *el; /* l'élément à ajouter dans la pile */ ret = malloc (size); /* on alloue normalement */ if (!ret) /* Si l'allocation à échoué, on affiche l'erreur et on quitte */ { perror ("xmalloc()"); exit (EXIT_FAILURE); } /* On ajoute l'addresse de l'allocation dans la pile */ el = malloc (sizeof (stack_s)); el->adr = ret; SLIST_INSERT_HEAD (&mstack, el, next); return ret; /* et on retourne l'addresse */ } |
Ainsi nous pouvons allouer tranquillement nos pointeurs avec xmalloc() en début de cycle, mais désormais il faut désallouer, pour cela il suffit de vider la pile en passant l'adresse de chaque élément à free() :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | void stack_delete (void) { stack_s *el; while (!SLIST_EMPTY (&mstack)) /* tant que la liste n'est pas vide */ { /* on récupère le premier élément que l'on supprime de la pile */ el = SLIST_FIRST (&mstack); SLIST_REMOVE_HEAD (&mstack, next); /* et on libère la mémoire */ free (el->adr); free (el); } } |
Il vous suffira désormais d'appeller cette fonction de temps en temps pour libérer la mémoire utilisé par votre programme, voici un exemple simple d'utilisation :
1 2 3 4 5 6 | for (;;) { variable = xmalloc (sizeof (*variable) * 23); /* suite de notre cycle */ stack_delete (); } |
Système plutot simple à mettre en oeuvre et assez rapide. Notez que vous pouvez également créer une fonction xfree() qui supprime directement l'élément de la pile, ici la fonction stack_delete() aurait plus un but de sécurité en cas d'oublie de libération de mémoire.
Cet article est tiré de cette publication Fait à la base par un ami ( ksh ) utilisateur de WMFS
| Author | Message |
|---|---|
titouille56
|
|
On verra demain...
Group : Member |
Dans la fonction xmalloc, pour le malloc de la ligne 15, il ne faudrait pas vérifier si la mémoire a bien été allouée ? |