Allocation dynamique de mémoire en C : Maîtriser malloc, calloc, realloc et free
Allocation dynamique de mémoire en C
Ce guide vous explique l'allocation dynamique de mémoire en C en utilisant les fonctions de la bibliothèque standard malloc(), calloc(), realloc() et free(), avec des exemples clairs et des conseils de bonnes pratiques.
Pourquoi utiliser l'allocation dynamique ?
Les tableaux statiques ont une taille fixe déclarée à la compilation, ce qui peut entraîner un gaspillage d'espace ou une capacité insuffisante lors de l'exécution. L'allocation dynamique permet de demander exactement la quantité de mémoire nécessaire pendant que le programme s'exécute.
Les quatre fonctions sont définies dans l'en-tête <stdlib.h> et fournissent un moyen contrôlé de gérer la mémoire du tas (heap).
malloc() – Allouer un bloc d'octets
Le nom malloc signifie « memory allocation ». Il réserve un bloc contigu de mémoire de la taille spécifiée (en octets) et retourne un pointeur de type void * qui peut être casté vers n'importe quel autre type de pointeur.
Syntaxe
ptr = malloc(size_in_bytes); // cast vers le type désiré si nécessaire
Exemple
float *ptr = malloc(100 * sizeof(float)); // 400 octets sur la plupart des systèmes
Ici, ptr pointe vers le premier octet d'un bloc de 400 octets. Si la requête échoue, malloc retourne NULL. Il est recommandé d'éviter les casts inutiles en C ; le compilateur peut déduire le type quand vous assignez le résultat à un pointeur typé.
calloc() – Allouer et initialiser à zéro
calloc signifie « contiguous allocation ». Contrairement à malloc, il initialise chaque bit du bloc alloué à zéro, le rendant sûr pour les types numériques et les pointeurs.
Syntaxe
ptr = calloc(num_elements, size_of_each_element);
Exemple
float *ptr = calloc(25, sizeof(float)); // 25 éléments float initialisés à zéro
Le pointeur retourné est NULL si l'allocation échoue.
free() – Libérer la mémoire allouée
La mémoire obtenue avec malloc ou calloc persiste jusqu'à ce que vous la libériez explicitement. free() désalloue le bloc et retourne la mémoire au tas pour une réutilisation future.
Syntaxe
free(ptr);
Appeler free sur un pointeur NULL est sûr et ne fait rien.
Exemple 1 : Utilisation de malloc() et free()
#include <stdio.h>
#include <stdlib.h>
int main(void) {
int n, i, *ptr, sum = 0;
printf("Entrez le nombre d'éléments : ");
scanf("%d", &n);
ptr = malloc(n * sizeof(int));
if (!ptr) {
fprintf(stderr, "Erreur : mémoire non allouée.\n");
return EXIT_FAILURE;
}
printf("Entrez les éléments : ");
for (i = 0; i < n; ++i) {
scanf("%d", ptr + i);
sum += *(ptr + i);
}
printf("Somme = %d\n", sum);
free(ptr);
return EXIT_SUCCESS;
}
Sortie
Entrez le nombre d'éléments : 3
Entrez les éléments : 100 20 36
Somme = 156
Exemple 2 : Utilisation de calloc() et free()
#include <stdio.h>
#include <stdlib.h>
int main(void) {
int n, i, *ptr, sum = 0;
printf("Entrez le nombre d'éléments : ");
scanf("%d", &n);
ptr = calloc(n, sizeof(int));
if (!ptr) {
fprintf(stderr, "Erreur : mémoire non allouée.\n");
return EXIT_FAILURE;
}
printf("Entrez les éléments : ");
for (i = 0; i < n; ++i) {
scanf("%d", ptr + i);
sum += *(ptr + i);
}
printf("Somme = %d\n", sum);
free(ptr);
return EXIT_SUCCESS;
}
Sortie
Entrez le nombre d'éléments : 3
Entrez les éléments : 100 20 36
Somme = 156
realloc() – Redimensionner une allocation existante
Si vous découvrez que votre allocation actuelle est trop petite ou plus grande que nécessaire, realloc() ajuste la taille tout en préservant les données existantes (jusqu'à la nouvelle taille).
Syntaxe
ptr = realloc(ptr, new_size_in_bytes);
Il retourne un pointeur vers le bloc réalloué ou NULL en cas d'échec. Pour éviter les fuites mémoire, stockez le résultat dans un pointeur temporaire d'abord.
Exemple 3 : Utilisation de realloc()
#include <stdio.h>
#include <stdlib.h>
int main(void) {
int *ptr, i, n1, n2;
printf("Entrez la taille initiale : ");
scanf("%d", &n1);
ptr = malloc(n1 * sizeof(int));
if (!ptr) {
fprintf(stderr, "Allocation échouée.\n");
return EXIT_FAILURE;
}
printf("Adresses avant réallocation :\n");
for (i = 0; i < n1; ++i) printf("%p\n", ptr + i);
printf("\nEntrez la nouvelle taille : ");
scanf("%d", &n2);
int *tmp = realloc(ptr, n2 * sizeof(int));
if (!tmp) {
fprintf(stderr, "Réallocation échouée.\n");
free(ptr);
return EXIT_FAILURE;
}
ptr = tmp;
printf("Adresses après réallocation :\n");
for (i = 0; i < n2; ++i) printf("%p\n", ptr + i);
free(ptr);
return EXIT_SUCCESS;
}
Sortie typique
Entrez la taille initiale : 2
Adresses avant réallocation :
0x7ffc12345670
0x7ffc12345674
Entrez la nouvelle taille : 4
Adresses après réallocation :
0x7ffc12345670
0x7ffc12345674
0x7ffc12345678
0x7ffc1234567c
En maîtrisant ces quatre fonctions et en appliquant une gestion d'erreurs appropriée, vous pouvez gérer la mémoire du tas de manière sûre et efficace dans toute application C.
Langue C
- Comprendre ROM, PROM, EPROM et EEPROM : conception, programmation et identification
- Microprocesseurs : l'évolution de l'informatique à programme stocké
- Maîtriser la gestion de mémoire en C++ : Utilisation experte de new et delete
- Cervoz lance la mémoire DDR4‑2666 pour l'IA industrielle et les solutions IoT
- Maîtriser l'allocation de tableaux dynamiques en C++ : Guide pratique avec exemples de code
- calloc() en C : Allocation mémoire initialisée à zéro et exemple pratique
- Utilisation de realloc() en C : Syntaxe, bonnes pratiques et exemple
- Gestion de la mémoire dynamique en C : calloc, malloc et free expliqués
- Le pricing dynamique revient dans le retail traditionnel : Pourquoi c'est inévitable