Lorsque vous travaillez en langage C, vous aurez souvent besoin de gérer la mémoire dynamiquement. Deux des fonctions les plus couramment utilisées pour allouer de la mémoire dynamiquement sont malloc()
et calloc()
. Bien qu’elles aient des fonctionnalités similaires, il existe des différences importantes entre les deux. Ce guide détaillé vise à expliquer ces différences pour vous aider à choisir la fonction la plus appropriée en fonction de vos besoins.
malloc()
La fonction malloc()
est utilisée pour allouer de la mémoire dynamiquement dans le tas (heap) en C. Elle prend en argument la taille en octets de la mémoire à allouer et renvoie un pointeur vers la mémoire allouée si l’allocation réussit, sinon elle renvoie NULL
.
void *malloc(size_t taille);
taille
: Nombre d’octets à allouer.malloc()
:#include <stdlib.h>
int main() {
int *ptr;
ptr = (int *)malloc(5 * sizeof(int)); // Alloue de la mémoire pour 5 entiers
if (ptr == NULL) {
// Gestion de l'échec de l'allocation
} else {
// Utilisation de la mémoire allouée
}
return 0;
}
calloc()
La fonction calloc()
est également utilisée pour allouer de la mémoire dynamiquement dans le tas en C. Cependant, elle prend deux arguments : le nombre d’éléments à allouer et la taille de chaque élément en octets. Elle initialise également la mémoire allouée à zéro. Comme malloc()
, si l’allocation réussit, elle renvoie un pointeur vers la mémoire allouée, sinon elle renvoie NULL
.
void *calloc(size_t nb_elements, size_t taille_element);
nb_elements
: Nombre d’éléments à allouer.taille_element
: Taille en octets de chaque élément.calloc()
:#include <stdlib.h>
int main() {
int *ptr;
ptr = (int *)calloc(5, sizeof(int)); // Alloue de la mémoire pour 5 entiers initialisés à zéro
if (ptr == NULL) {
// Gestion de l'échec de l'allocation
} else {
// Utilisation de la mémoire allouée
}
return 0;
}
malloc()
et calloc()
malloc()
: La mémoire allouée n’est pas initialisée. Son contenu est indéterminé.calloc()
: La mémoire allouée est initialisée à zéro pour tous ses octets.malloc()
: Prend un seul argument représentant la taille totale en octets de la mémoire à allouer.calloc()
: Prend deux arguments : le nombre d’éléments à allouer et la taille de chaque élément en octets.malloc()
peut être légèrement plus performant que calloc()
car il n’effectue pas d’initialisation supplémentaire.Voici quelques exemples d’application avec des sous-titres et des extraits de code pour illustrer l’utilisation de malloc()
et calloc()
dans des situations courantes :
Dans cet exemple, nous allons allouer de la mémoire pour un tableau d’entiers à l’aide de malloc()
et calloc()
, puis initialiser et afficher les valeurs du tableau.
malloc()
:#include <stdio.h>
#include <stdlib.h>
int main() {
int *ptr;
int taille = 5;
ptr = (int *)malloc(taille * sizeof(int));
if (ptr == NULL) {
printf("Erreur d'allocation de mémoire\n");
return 1;
}
// Initialisation du tableau
for (int i = 0; i < taille; i++) {
ptr[i] = i + 1;
}
// Affichage du tableau
printf("Tableau alloué avec malloc(): ");
for (int i = 0; i < taille; i++) {
printf("%d ", ptr[i]);
}
// Libération de la mémoire
free(ptr);
return 0;
}
calloc()
:#include <stdio.h>
#include <stdlib.h>
int main() {
int *ptr;
int taille = 5;
ptr = (int *)calloc(taille, sizeof(int));
if (ptr == NULL) {
printf("Erreur d'allocation de mémoire\n");
return 1;
}
// Pas besoin d'initialisation, tous les éléments sont déjà initialisés à zéro avec calloc()
// Affichage du tableau
printf("Tableau alloué avec calloc(): ");
for (int i = 0; i < taille; i++) {
printf("%d ", ptr[i]);
}
// Libération de la mémoire
free(ptr);
return 0;
}
Dans cet exemple, nous allons allouer de la mémoire pour une chaîne de caractères (une chaîne terminée par un caractère nul) à l’aide de malloc()
et calloc()
, puis initialiser et afficher la chaîne.
malloc()
:#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main() {
char *ptr;
int taille = 10;
ptr = (char *)malloc(taille * sizeof(char));
if (ptr == NULL) {
printf("Erreur d'allocation de mémoire\n");
return 1;
}
// Initialisation de la chaîne
strcpy(ptr, "Hello");
// Affichage de la chaîne
printf("Chaîne allouée avec malloc(): %s\n", ptr);
// Libération de la mémoire
free(ptr);
return 0;
}
calloc()
:#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main() {
char *ptr;
int taille = 10;
ptr = (char *)calloc(taille, sizeof(char));
if (ptr == NULL) {
printf("Erreur d'allocation de mémoire\n");
return 1;
}
// Initialisation de la chaîne
strcpy(ptr, "Hello");
// Affichage de la chaîne
printf("Chaîne allouée avec calloc(): %s\n", ptr);
// Libération de la mémoire
free(ptr);
return 0;
}
Ces exemples illustrent comment utiliser malloc()
et calloc()
pour allouer de la mémoire dynamiquement dans des situations concrètes, en prenant en compte l’initialisation de la mémoire et la libération ultérieure de la mémoire allouée.
Voici quelques cas particuliers où l’utilisation de malloc()
et calloc()
peut être adaptée en fonction des besoins spécifiques.
Parfois, vous pourriez avoir besoin d’allouer une grande quantité de mémoire, par exemple pour traiter de grands ensembles de données. Dans de tels cas, les performances peuvent être un facteur critique.
malloc()
:#include <stdio.h>
#include <stdlib.h>
int main() {
int *ptr;
long long int taille = 1000000000LL; // 1 milliard d'entiers
ptr = (int *)malloc(taille * sizeof(int));
if (ptr == NULL) {
printf("Erreur d'allocation de mémoire\n");
return 1;
}
// Utilisation de la mémoire allouée
// Libération de la mémoire
free(ptr);
return 0;
}
Dans ce cas, malloc()
peut être plus adapté car elle est généralement plus rapide que calloc()
pour de grandes allocations, car calloc()
doit initialiser la mémoire à zéro.
Lorsque vous allouez de la mémoire pour des structures de données complexes, telles que des structures imbriquées ou des tableaux de structures, vous devez tenir compte de l’initialisation de chaque élément.
calloc()
pour une initialisation à zéro :#include <stdio.h>
#include <stdlib.h>
typedef struct {
int a;
float b;
} MyStruct;
int main() {
MyStruct *ptr;
int taille = 10;
ptr = (MyStruct *)calloc(taille, sizeof(MyStruct));
if (ptr == NULL) {
printf("Erreur d'allocation de mémoire\n");
return 1;
}
// Utilisation de la mémoire allouée
// Libération de la mémoire
free(ptr);
return 0;
}
Dans ce cas, l’utilisation de calloc()
garantit que toutes les structures sont initialisées à zéro, ce qui peut être utile pour éviter des valeurs indéterminées dans les structures.
Lorsque vous allouez de la mémoire pour des chaînes de caractères, vous devez tenir compte de la terminaison de la chaîne par un caractère nul ('\0'
).
malloc()
pour une allocation sans initialisation :#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main() {
char *ptr;
int taille = 10;
ptr = (char *)malloc((taille + 1) * sizeof(char)); // +1 pour le caractère nul
if (ptr == NULL) {
printf("Erreur d'allocation de mémoire\n");
return 1;
}
// Utilisation de la mémoire allouée
// Libération de la mémoire
free(ptr);
return 0;
}
Dans cet exemple, nous ajoutons un octet supplémentaire pour le caractère nul qui termine la chaîne de caractères. Nous n’avons pas besoin d’initialiser explicitement la mémoire, car malloc()
ne garantit pas que la mémoire est initialisée.
Ces exemples mettent en évidence des cas particuliers où le choix entre malloc()
et calloc()
dépend des besoins spécifiques de votre programme, tels que la performance, l’initialisation de la mémoire et la gestion de structures de données complexes.
En résumé, malloc()
et calloc()
sont tous deux utilisés pour allouer de la mémoire dynamiquement en C, mais ils diffèrent par leur manière de gérer la mémoire allouée et leurs arguments. Le choix entre les deux dépend des besoins spécifiques de votre programme, en tenant compte de l’initialisation de la mémoire et de la performance.
Cet article vous aidera à mieux rédiger un projet de reprise d'entreprise. Ci-après les étapes…
Exprimer un jugement sur une autre personne est une démarche délicate qui nécessite tact, respect…
Exercice 1 : Détection du Stock Dormant Une entreprise a les données suivantes pour un…
Le stock en transit, aussi appelé stock en cours de transport, désigne les biens ou…
Le stock dormant (aussi appelé stock obsolète ou inutilisé) désigne les articles ou les biens…
La fiche hebdomadaire de travail est un outil simple mais puissant pour organiser ses tâches,…
This website uses cookies.