La fonction malloc
(memory allocation) en langage C est utilisée pour allouer dynamiquement de la mémoire à l’exécution. Ce guide explique en détail son utilisation, ses applications, et les bonnes pratiques.
malloc
?malloc
est définie dans <stdlib.h>
.NULL
.malloc
void *malloc(size_t size);
size
: Taille en octets de la mémoire à allouer.void *
(générique), à convertir dans le type approprié.malloc
<stdlib.h>
.sizeof
.free
.#include <stdio.h>
#include <stdlib.h>
int main() {
// Allocation d'un entier
int *ptr = (int *)malloc(sizeof(int));
if (ptr == NULL) {
printf("Échec de l'allocation mémoire.\n");
return 1;
}
*ptr = 42; // Initialisation de l'entier
printf("Valeur de l'entier alloué : %d\n", *ptr);
free(ptr); // Libération de la mémoire
return 0;
}
#include <stdio.h>
#include <stdlib.h>
int main() {
int n;
printf("Entrez la taille du tableau : ");
scanf("%d", &n);
// Allocation d'un tableau d'entiers
int *tableau = (int *)malloc(n * sizeof(int));
if (tableau == NULL) {
printf("Échec de l'allocation mémoire.\n");
return 1;
}
// Initialisation des éléments
for (int i = 0; i < n; i++) {
tableau[i] = i * 2;
}
// Affichage des éléments
printf("Éléments du tableau : ");
for (int i = 0; i < n; i++) {
printf("%d ", tableau[i]);
}
printf("\n");
// Libération de la mémoire
free(tableau);
return 0;
}
malloc
#include <stdio.h>
#include <stdlib.h>
int main() {
int lignes = 3, colonnes = 4;
// Allocation d'une matrice linéarisée
int *matrice = (int *)malloc(lignes * colonnes * sizeof(int));
if (matrice == NULL) {
printf("Échec de l'allocation mémoire.\n");
return 1;
}
// Initialisation et affichage
for (int i = 0; i < lignes; i++) {
for (int j = 0; j < colonnes; j++) {
matrice[i * colonnes + j] = i + j;
printf("%d ", matrice[i * colonnes + j]);
}
printf("\n");
}
free(matrice); // Libération de la mémoire
return 0;
}
#include <stdio.h>
#include <stdlib.h>
int main() {
int lignes = 3, colonnes = 4;
// Allocation d'un tableau de pointeurs
int **matrice = (int **)malloc(lignes * sizeof(int *));
if (matrice == NULL) {
printf("Échec de l'allocation mémoire.\n");
return 1;
}
// Allocation de chaque ligne
for (int i = 0; i < lignes; i++) {
matrice[i] = (int *)malloc(colonnes * sizeof(int));
if (matrice[i] == NULL) {
printf("Échec de l'allocation mémoire pour la ligne %d.\n", i);
return 1;
}
}
// Initialisation et affichage
for (int i = 0; i < lignes; i++) {
for (int j = 0; j < colonnes; j++) {
matrice[i][j] = i * j;
printf("%d ", matrice[i][j]);
}
printf("\n");
}
// Libération de la mémoire
for (int i = 0; i < lignes; i++) {
free(matrice[i]);
}
free(matrice);
return 0;
}
realloc
La fonction realloc
permet de redimensionner un bloc mémoire alloué avec malloc
.
void *realloc(void *ptr, size_t size);
ptr
: Pointeur vers le bloc initial.size
: Nouvelle taille souhaitée.#include <stdio.h>
#include <stdlib.h>
int main() {
int n = 5;
// Allocation initiale
int *tableau = (int *)malloc(n * sizeof(int));
if (tableau == NULL) {
printf("Échec de l'allocation mémoire.\n");
return 1;
}
for (int i = 0; i < n; i++) {
tableau[i] = i + 1;
}
// Redimensionnement
printf("Redimensionnement du tableau à 10 éléments.\n");
tableau = (int *)realloc(tableau, 10 * sizeof(int));
if (tableau == NULL) {
printf("Échec de la réallocation mémoire.\n");
return 1;
}
// Initialisation des nouveaux éléments
for (int i = n; i < 10; i++) {
tableau[i] = i + 1;
}
// Affichage
for (int i = 0; i < 10; i++) {
printf("%d ", tableau[i]);
}
printf("\n");
free(tableau);
return 0;
}
malloc
malloc
échoue, il retourne NULL
. Utilisez toujours une vérification après l’allocation.malloc
doit être libérée avec free
pour éviter les fuites mémoire.free
, le pointeur est invalide. Il est recommandé de le réinitialiser à NULL
.sizeof
pour calculer correctement la taille des types de données.calloc
malloc
ne met pas à zéro les blocs de mémoire alloués. Les valeurs sont indéterminées.calloc
.Exemple avec calloc
:
int *tableau = (int *)calloc(5, sizeof(int));
En C, malloc
est l’une des méthodes les plus couramment utilisées pour l’allocation dynamique de mémoire. Cependant, il existe plusieurs alternatives à malloc
, qui offrent des fonctionnalités supplémentaires ou adaptées à des besoins spécifiques. Voici un aperçu des alternatives :
calloc
malloc
, mais initialise les blocs à zéro.void *calloc(size_t nitems, size_t size);
nitems
: Nombre d’éléments à allouer.size
: Taille de chaque élément.int *array = (int *)calloc(10, sizeof(int)); if (array == NULL) { printf("Allocation mémoire échouée.\n"); }
realloc
malloc
ou calloc
.void *realloc(void *ptr, size_t new_size);
ptr
: Pointeur vers la mémoire initiale.new_size
: Nouvelle taille en octets.int *array = (int *)malloc(5 * sizeof(int)); array = (int *)realloc(array, 10 * sizeof(int)); // Agrandir à 10 éléments
free
free
est nécessaire pour libérer la mémoire allouée dynamiquement.void free(void *ptr);
free
pour éviter les fuites mémoire.NULL
après un free
.free(array); array = NULL;
alloca
void *alloca(size_t size);
free
.int *array = (int *)alloca(10 * sizeof(int));
new
(en C++)int *array = new int[10]; delete[] array; // Libération en C++
VirtualAlloc
et mmap
(allocations spécifiques au système)VirtualAlloc
(Windows)void *VirtualAlloc(LPVOID lpAddress, SIZE_T dwSize, DWORD flAllocationType, DWORD flProtect);
#include <windows.h> void *ptr = VirtualAlloc(NULL, 1024, MEM_COMMIT, PAGE_READWRITE);
mmap
(Linux/Unix)void *mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset);
#include <sys/mman.h> void *ptr = mmap(NULL, 4096, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
HeapAlloc
(Windows)LPVOID HeapAlloc(HANDLE hHeap, DWORD dwFlags, SIZE_T dwBytes);
#include <windows.h> HANDLE heap = GetProcessHeap(); void *ptr = HeapAlloc(heap, 0, 1024);
std::vector
et std::array
(en C++ uniquement)std::vector
: #include <vector> std::vector<int> vec(10); // Tableau dynamique de taille 10
Certaines bibliothèques ou outils fournissent des fonctions spécifiques pour gérer la mémoire :
jemalloc
: Allocation efficace pour les charges lourdes.tcmalloc
(Google) : Optimisé pour les applications multithreadées.Boehm GC
: Collecteur de mémoire automatique pour les langages C/C++.Méthode | Type de mémoire | Initialisation | Besoin de free | Applications courantes |
---|---|---|---|---|
malloc | Tas | Non | Oui | Allocation générale. |
calloc | Tas | Oui (zéro) | Oui | Tableaux dynamiques. |
realloc | Tas | Conserve données existantes | Oui | Redimensionnement de blocs. |
alloca | Pile | Non | Non | Mémoire temporaire (locale). |
VirtualAlloc | Mémoire virtuelle | Non | Oui | Grandes allocations (Windows). |
mmap | Mémoire virtuelle | Non | Oui | Gestion avancée (Linux/Unix). |
HeapAlloc | Tas (Windows) | Non | Oui | Gestion de tas multiples. |
new (C++) | Tas | Non | Oui (delete ) | Objets dynamiques en C++. |
L’alternative à malloc
dépend du contexte et des besoins spécifiques :
calloc
ou realloc
.mmap
ou VirtualAlloc
.std::vector
en C++.
Oui, il est possible de combiner malloc
et calloc
dans un programme, mais cela dépend du contexte et du besoin spécifique. Les deux fonctions sont utilisées pour allouer dynamiquement de la mémoire, mais elles ont des différences importantes :
malloc
: Alloue un bloc de mémoire, mais ne l’initialise pas (les valeurs dans la mémoire sont indéterminées).calloc
: Alloue un bloc de mémoire et initialise tous les bits à zéro.Combiner les deux signifie généralement utiliser l’une pour une partie du programme et l’autre pour une autre partie, selon le besoin. Voici quelques cas où cette combinaison peut être utile :
Vous pouvez utiliser malloc
pour une partie du programme où l’initialisation à zéro n’est pas nécessaire, et calloc
pour une autre partie où vous avez besoin de mémoire initialisée.
#include <stdio.h>
#include <stdlib.h>
int main() {
int n = 5;
// Utilisation de malloc
int *array1 = (int *)malloc(n * sizeof(int));
if (array1 == NULL) {
printf("Échec de l'allocation avec malloc.\n");
return 1;
}
// Initialisation manuelle des éléments
for (int i = 0; i < n; i++) {
array1[i] = i + 1;
}
printf("Tableau array1 (malloc) : ");
for (int i = 0; i < n; i++) {
printf("%d ", array1[i]);
}
printf("\n");
// Utilisation de calloc
int *array2 = (int *)calloc(n, sizeof(int));
if (array2 == NULL) {
printf("Échec de l'allocation avec calloc.\n");
free(array1);
return 1;
}
// array2 est déjà initialisé à 0
printf("Tableau array2 (calloc) : ");
for (int i = 0; i < n; i++) {
printf("%d ", array2[i]);
}
printf("\n");
// Libération de la mémoire
free(array1);
free(array2);
return 0;
}
malloc
puis d’une initialisation avec calloc
Une combinaison moins courante consiste à allouer une mémoire avec malloc
et à utiliser une autre portion de mémoire allouée avec calloc
pour initialiser certains éléments.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main() {
int n = 5;
// Allocation avec malloc
int *array = (int *)malloc(n * sizeof(int));
if (array == NULL) {
printf("Échec de l'allocation avec malloc.\n");
return 1;
}
// Initialisation manuelle de la première moitié
for (int i = 0; i < n / 2; i++) {
array[i] = i + 1;
}
// Allocation d'un autre bloc avec calloc et copie dans l'autre moitié
int *temp = (int *)calloc(n / 2, sizeof(int));
if (temp == NULL) {
printf("Échec de l'allocation avec calloc.\n");
free(array);
return 1;
}
memcpy(&array[n / 2], temp, (n / 2) * sizeof(int)); // Copie mémoire initialisée à 0
// Affichage du tableau combiné
printf("Tableau combiné : ");
for (int i = 0; i < n; i++) {
printf("%d ", array[i]);
}
printf("\n");
// Libération
free(array);
free(temp);
return 0;
}
Si vous gérez des structures complexes avec plusieurs champs, vous pouvez allouer une partie de la structure avec malloc
et une autre avec calloc
, en fonction des besoins d’initialisation.
#include <stdio.h>
#include <stdlib.h>
typedef struct {
int *values; // Mémoire allouée avec malloc
int *flags; // Mémoire allouée avec calloc
} Data;
int main() {
int n = 5;
// Allocation de la structure
Data *data = (Data *)malloc(sizeof(Data));
if (data == NULL) {
printf("Échec de l'allocation de la structure.\n");
return 1;
}
// Allocation des champs
data->values = (int *)malloc(n * sizeof(int));
data->flags = (int *)calloc(n, sizeof(int));
if (data->values == NULL || data->flags == NULL) {
printf("Échec de l'allocation des champs.\n");
free(data->values);
free(data->flags);
free(data);
return 1;
}
// Initialisation des valeurs
for (int i = 0; i < n; i++) {
data->values[i] = i + 1;
}
// Affichage
printf("Values : ");
for (int i = 0; i < n; i++) {
printf("%d ", data->values[i]);
}
printf("\nFlags : ");
for (int i = 0; i < n; i++) {
printf("%d ", data->flags[i]);
}
printf("\n");
// Libération
free(data->values);
free(data->flags);
free(data);
return 0;
}
malloc
et calloc
calloc
lorsque vous avez besoin d’un tableau ou d’une structure initialisée à zéro.malloc
si vous n’avez pas besoin d’une initialisation explicite, pour des raisons de performance.malloc
et calloc
pour éviter les plantages dus à un manque de mémoire.free
.
Exercice 1 : Calcul des Écarts sur Volume et Prix Contexte :Une entreprise a prévu…
1. Généralités sur le Contrôle Budgétaire Question 1 : Quel est l’objectif principal du contrôle…
Voici un QCM Contrôle de Gestion - Pilotage de la Performance bien conçu sur le…
Une fiche d’action est un outil essentiel pour planifier, suivre et gérer les tâches dans…
La fiche de parrainage est bien plus qu’un simple document administratif. Elle constitue un outil…
La tenue de registres est une méthode essentielle pour organiser et gérer des informations de…
This website uses cookies.