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.mallocvoid *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;
}
reallocLa 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;
}
mallocmalloc é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.callocmalloc 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 :
callocmalloc, 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"); }reallocmalloc 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émentsfreefree 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;allocavoid *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 10Certaines 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 callocUne 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 calloccalloc 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.
Prendre une décision d’investissement n’a jamais été un simple exercice arithmétique. Derrière chaque projet se…
Quand on parle de nature des mots, beaucoup d’élèves ont l’impression d’entrer dans un chapitre…
Si la trigonométrie te paraît floue, rassure-toi : en 3ème, elle repose sur quelques réflexes…
Si vous voulez connaître votre signe chinois sans passer par des tableaux interminables, vous êtes…
Quand on finance une voiture, tout le monde voit à peu près de quoi il…
On connaît tous ce moment : on tombe sur une offre de leasing “à partir…
This website uses cookies.