En langage C, le programmeur gère la mémoire directement : l'allocation, la désallocation et l'utilisation des tableaux, des structures et des pointeurs sont contrôlées manuellement. Le mécanisme d'allocation dynamique de mémoire existe en C depuis les années 1970 et est implémenté via des fonctions spécifiques de la bibliothèque standard (malloc, calloc, realloc, free). Cette approche offre des performances et de la flexibilité, mais nécessite de la prudence.
Une erreur dans la gestion de la mémoire peut entraîner des fuites, la corruption d'autres données, des plantages de programme ou des vulnérabilités de sécurité. Les erreurs surviennent souvent à cause d'appels free oubliés, de débordements de tableaux, de castings de pointeurs incorrects ou de double désallocation. Pour les structures, la situation est similaire, mais le risque d'oublier de nettoyer les champs dynamiques imbriqués s'ajoute.
Pour minimiser les erreurs, il est recommandé de développer un code strictement structuré, de suivre toutes les allocations et désallocations de mémoire, de ne pas utiliser des pointeurs désalloués et de surveiller la taille des tableaux alloués. Il est important d'utiliser des outils d'analyse statique, des vérifications finales (valgrind, sanitizers), ainsi que de respecter les conventions : celui qui appelle malloc doit aussi libérer la mémoire.
Exemple de code :
#include <stdio.h> #include <stdlib.h> typedef struct { int *arr; size_t size; } ArrayWrapper; ArrayWrapper *create(size_t n) { ArrayWrapper *aw = malloc(sizeof(ArrayWrapper)); if (!aw) return NULL; aw->arr = malloc(sizeof(int) * n); if (!aw->arr) { free(aw); return NULL; } aw->size = n; return aw; } void destroy(ArrayWrapper *aw) { if (aw) { free(aw->arr); free(aw); } }
Caractéristiques clés :
Que se passe-t-il lors de la désallocation de la mémoire via un pointeur nul (free(NULL)) ?
Selon la norme C, l'appel de free sur un pointeur nul est sûr - rien ne se passe, aucune erreur ne se produit. C'est pratique pour transférer la responsabilité de la libération de la mémoire.
Peut-on utiliser la mémoire après un appel à free ?
Non, utiliser la mémoire après sa libération (use-after-free) est une erreur classique. Les données peuvent changer ou la zone peut être réattribuée à un autre processus. Il est toujours conseillé de mettre le pointeur à NULL après un free.
int *ptr = malloc(10); free(ptr); ptr = NULL; // Sûr
Est-il nécessaire de libérer toute la mémoire allouée avant la sortie du programme ?
Techniquement non - à la fin du programme, le système d'exploitation libère toutes les ressources. Mais ignorer la libération de la mémoire est un anti-modèle qui complique le débogage et peut entraîner des erreurs dans de gros programmes s'exécutant longtemps.
Un développeur crée des tableaux dynamiques à l'intérieur d'une fonction, oubliant de les nettoyer :
Avantages :
Inconvénients :
Tout le code passe par une vérification d'analyse statique, tous les pointeurs sont remis à NULL après free, chaque malloc est accompagné d'un free :
Avantages :
Inconvénients :