Allouer la mémoire de structure avec malloc en C

Jinku Hu 12 octobre 2023
  1. Utiliser malloc avec l’opérateur sizeof pour allouer la mémoire de structure en C
  2. Utilisez la boucle for pour allouer de la mémoire à un ensemble de structures en C
Allouer la mémoire de structure avec malloc 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);
}
Auteur: Jinku Hu
Jinku Hu avatar Jinku Hu avatar

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

Article connexe - C Struct