malloc
malloc
est en informatique une fonction de la bibliothèque standard du langage C permettant d'allouer dynamiquement de la mémoire. La libération de la mémoire ainsi réservée s'effectue avec la fonction free
.
Cette fonction est déclarée dans l'en-tête <stdlib.h>
. Dans les systèmes GNU/Linux, elle fait partie du paquet GNU C Library.
Allocation de mémoire
L'allocation de mémoire pour un programme peut s'effectuer de trois manières :
- statiquement, au cours de la compilation par la déclaration de variables statiques : variables globales ou variables locales déclarées en utilisant le mot-clé
static
, - dynamiquement, au cours de l'exécution :
- soit de façon automatique sur la pile d'exécution : variables locales déclarées dans un bloc d'instructions,
- soit à la demande sur le tas : en utilisant des fonctions d'allocation de la mémoire.
L'allocation statique oblige le développeur à connaître à l'avance la quantité de mémoire qui sera utilisée par le programme. C'est ainsi qu'un « gaspillage » de la mémoire peut survenir si l'on réserve trop de mémoire par rapport à ce dont le programme a véritablement besoin pour réaliser la tâche qui lui incombe.
Avec l'allocation automatique, la libération de la mémoire n'est réalisée qu'à la fin du bloc d'instructions dans lequel est déclarée la variable, ce qui peut également être un facteur de gaspillage lorsque de la mémoire est allouée, mais n'est plus utilisée.
C'est ici que l'allocation dynamique de mémoire entre en jeu. La réservation de la mémoire se fait au cours de l'exécution du programme, mais la libération de cette mémoire n'est plus gérée par le compilateur, mais par le programmeur. Cela augmente la complexité du programme, mais la gestion de la mémoire est plus fine.
Si un programme alloue de la mémoire par malloc
sans la libérer ensuite par free
, on parle de fuite de mémoire. Pour éviter ce type de bug et faciliter l'écriture des programmes, certains langages disposent d'un mécanisme de ramasse-miettes, mais ce n'est pas le cas du langage C.
Utilisation
Deux fonctions permettent de réserver et de libérer dynamiquement une zone de la mémoire : malloc
pour la réservation, dont le prototype est le suivant :
void *malloc(size_t size);
Le seul paramètre à passer à malloc
est le nombre d'octets à allouer. La valeur retournée est l'adresse du premier octet de la zone mémoire allouée. Si l'allocation n'a pu se réaliser (par manque de mémoire libre), la valeur de retour est la constante NULL.
La libération de la mémoire précédemment allouée via malloc
est assurée par la fonction free
dont la déclaration est la suivante :
void free(void *ptr);
Le seul paramètre à passer est l'adresse du premier octet de la zone allouée et aucune valeur n'est retournée une fois cette opération réalisée.
Voici du code réservant 20 octets et le libérant immédiatement après si l'allocation a été effectuée.
#include <stdlib.h>
char * pointeur = malloc(20 * sizeof(char)); //Allocation de 20 octets (Un char est Ă©gal Ă 1 octet)
if(pointeur == NULL)
{
printf("L'allocation n'a pu être réalisée\n");
}
else
{
printf("L'allocation a été un succès\n");
free(pointeur); //Libération des 20 octets précédemment alloués
pointeur = NULL; // Invalidation du pointeur
}
Fonctions analogues
calloc
La zone mémoire allouée par malloc
n'est pas initialisée automatiquement. Cette initialisation peut être réalisée à l'aide de la fonction memset
ou bien par le parcours de toute la zone mémoire. Avec la fonction calloc
, cette phase d'initialisation n'est plus nécessaire, car la zone mémoire allouée est initialisée avec des 0.
La déclaration de calloc
est la suivante :
void *calloc(size_t nmemb, size_t size);
Le paramètre nmemb
est le nombre d'éléments que l'on désire réserver et size
correspond à la taille en octets d'un élément. La valeur retournée est la même que pour malloc
.
realloc
La fonction realloc
permet de modifier la taille de la mémoire allouée préalablement avec malloc
. S'il est nécessaire de déplacer la zone mémoire, car il n'y a pas assez de mémoire contiguë, la libération de l'ancienne zone mémoire est réalisée par realloc
via free
.
La déclaration de realloc
est la suivante :
void *realloc(void *ptr, size_t size);
Le paramètre ptr
désigne le début de la zone mémoire dont on désire modifier la taille. Le second paramètre, size
, est la nouvelle taille en octet de la zone mémoire.
Si la fonction réussit, la valeur retournée est le début de la zone mémoire allouée. Attention : la valeur du pointeur ptr
n'est plus valide car la nouvelle zone peut débuter à un autre endroit de la mémoire si un déplacement a été nécessaire.
Si la fonction Ă©choue, elle retourne la valeur NULL
. Des précautions doivent être prises pour éviter une fuite de mémoire. Il convient de veiller à ce que l'adresse de l'ancien bloc ne soit pas écrasée avant de s'assurer que la réallocation a bien réussi.
Exemple :
tampon = realloc(tampon, nouvelle_taille);
if (tampon == NULL)
rapporterErreur();
Ici, le test sur la valeur de tampon
n'est pas suffisant. Si realloc a échoué, l'adresse de la zone mémoire est perdue. La solution ci-dessous permet de remédier à ce problème :
tmp = realloc(tampon, nouvelle_taille);
if (tmp == NULL)
{
free(tampon);
rapporterErreur();
}
else
tampon = tmp;
DĂ©bogage
DĂ©bogage sous Windows
Des utilitaires graphiques permettent de vérifier que la mémoire utilisée est bien libérée lorsqu'elle n'est plus utilisée, comme c'est le cas avec MFC Debuging support qui est dédié à l'API MFC de Microsoft[1].
DĂ©bogage sous GNU/Linux
- mtrace, commande servant de débogueur de mémoire et distribuée avec le paquet GNU C Library ; elle permet de tracer les appels à malloc ;
- TotalView, Valgrind et mpatrol : débogueurs permettant de détecter les fuites de mémoire et les écritures hors de la zone allouée par malloc ;
- La bibliothèque logicielle DUMA aide à détecter indirectement les malloc ayant une taille trop petite ou trop grande ;
Notes et références
- (en) « MFC Debugging Support », Microsoft (consulté le )