Allouer la mémoire de structure avec malloc en C
-
Utiliser
malloc
avec l’opérateursizeof
pour allouer la mémoire de structure en C -
Utilisez la boucle
for
pour allouer de la mémoire à un ensemble de structures en C
Cet article explique plusieurs méthodes d’allocation de la mémoire de structure avec malloc
en C.
Utiliser malloc
avec l’opérateur sizeof
pour allouer la mémoire de structure en C
Malloc est la fonction centrale pour l’allocation dynamique de mémoire en C qui prend un seul argument entier représentant le nombre d’octets à allouer. Pour allouer la mémoire de l’objet struct
personnalisé qui a été défini, nous devons appeler l’opérateur sizeof
et récupérer la quantité de mémoire dont l’objet a besoin.
Notez que nous pouvons passer l’expression sizeof(MyObject)
directement dans l’appel malloc
en tant qu’argument. Une mise en garde à propos de malloc
est que la mémoire allouée avec succès n’est pas initialisée, ce qui signifie qu’il peut y avoir des valeurs de déchets stockées. Pour remédier à ce problème, la bibliothèque C fournit une autre fonction utile - calloc
pour initialiser automatiquement la zone de mémoire avec zéro. L’exemple suivant montre l’allocation de mémoire pour la structure unique MyObject
.
#include <stdio.h>
#include <stdlib.h>
enum VALID { FALSE, TRUE };
typedef struct {
int valid;
int *data;
size_t size;
} MyObject;
int main() {
int *tmp = NULL;
MyObject *my1 = malloc(sizeof(MyObject));
my1->valid = TRUE;
my1->data = tmp;
my1->size = sizeof tmp;
free(my1);
exit(EXIT_SUCCESS);
}
Utilisez la boucle for
pour allouer de la mémoire à un ensemble de structures en C
Il est souvent utile de déclarer un ensemble de structures, ce qui peut nécessiter une zone de mémoire plus importante que celle disponible sur la pile. Nous devons donc allouer le tableau en tant que mémoire dynamique. L’exemple de code suivant démontre le cas où le tableau de 100 pointeurs vers les structures MyObject
est déclaré sur la pile, mais où chaque objet MyObject
individuel est alloué en mémoire dynamique (heap).
Notez que nous avons également implémenté la fonction initMyObject
pour initialiser chaque membre dans MyObject
à des fins de test uniquement. La fonction retourne -1
si le pointeur passé est null
, et l’instruction if
est mise dans la boucle for
pour s’assurer que le message d’erreur correspondant est imprimé.
#include <stdio.h>
#include <stdlib.h>
#define MAX 100
enum VALID { FALSE, TRUE };
typedef struct {
int valid;
int *data;
size_t size;
} MyObject;
int initMyObject(MyObject *obj, int val, int *dat, size_t siz) {
if (!obj) return -1;
obj->valid = val;
obj->data = dat;
obj->size = siz;
return 0;
}
int main() {
int *tmp = NULL;
MyObject *arr[MAX];
for (int i = 0; i < MAX; ++i) {
arr[i] = malloc(sizeof(MyObject));
if (initMyObject(arr[i], TRUE, tmp, sizeof(tmp)) == -1) {
fprintf(stderr, "[ERROR] initMyObject() failed\n");
break;
}
}
printf("finished\n");
exit(EXIT_SUCCESS);
}
Cependant, il y a une partie erronée du programme précédent qui ne peut être autorisée dans aucun code de production. Le programme se termine sans désallouer les zones de mémoire qui ont été allouées dynamiquement dans la boucle. Notez que, comme pour l’allocation, chaque élément individuel du tableau doit être libéré. Ainsi, nous avons implémenté une fonction séparée, deallocMyObjectArray
, pour exécuter des appels itératifs à free
dans l’exemple de code suivant.
#include <stdio.h>
#include <stdlib.h>
#define MAX 100
enum VALID { FALSE, TRUE };
typedef struct {
int valid;
int *data;
size_t size;
} MyObject;
int initMyObject(MyObject *obj, int val, int *dat, size_t siz) {
if (!obj) return -1;
obj->valid = val;
obj->data = dat;
obj->size = siz;
return 0;
}
int deallocMyObjectArray(MyObject *arr[], size_t len) {
if (!arr) return -1;
for (int i = 0; i < len; ++i) free(arr[i]);
return 0;
}
int main() {
int *tmp = NULL;
MyObject *arr[MAX];
for (int i = 0; i < MAX; ++i) {
arr[i] = malloc(sizeof(MyObject));
if (initMyObject(arr[i], TRUE, tmp, sizeof(tmp)) == -1) {
fprintf(stderr, "[ERROR] initMyObject() failed\n");
break;
}
}
deallocMyObjectArray(arr, MAX);
printf("finished\n");
exit(EXIT_SUCCESS);
}
Founder of DelftStack.com. Jinku has worked in the robotics and automotive industries for over 8 years. He sharpened his coding skills when he needed to do the automatic testing, data collection from remote servers and report creation from the endurance test. He is from an electrical/electronics engineering background but has expanded his interest to embedded electronics, embedded programming and front-/back-end programming.
LinkedIn Facebook