Allocare la memoria Struct con malloc in C

Jinku Hu 12 ottobre 2023
  1. Usa malloc con l’operatore sizeof per allocare la memoria Struct in C
  2. Usa il cicli for per allocare la memoria per un array di strutture in C
Allocare la memoria Struct con malloc in C

Questo articolo spiegherà diversi metodi su come allocare la memoria della struttura con malloc in C.

Usa malloc con l’operatore sizeof per allocare la memoria Struct in C

malloc è la funzione principale per l’allocazione dinamica della memoria in C che accetta un singolo argomento intero che rappresenta il numero di byte da allocare. Per allocare la memoria dell’oggetto personalizzato struct che è stato definito, dovremmo chiamare l’operatore sizeof e recuperare la quantità di memoria di cui ha bisogno l’oggetto.

Nota che possiamo passare l’espressione sizeof(MyObject) direttamente nella chiamata malloc come argomento. Un avvertimento su malloc è che la memoria allocata con successo non viene inizializzata, il che significa che potrebbero esserci alcuni valori di spazzatura memorizzati. Per ovviare a questo problema, la libreria C fornisce un’altra utile funzione - calloc per inizializzare automaticamente la regione di memoria con zero. Il seguente esempio mostra l’allocazione della memoria per la singola struttura 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);
}

Usa il cicli for per allocare la memoria per un array di strutture in C

È spesso utile dichiarare un array di strutture, che potrebbe richiedere un’area di memoria più grande di quella disponibile nello stack. Quindi, dobbiamo allocare l’array come memoria dinamica. Il seguente codice di esempio mostra il caso in cui l’array di 100 puntatori agli struct MyObject è dichiarato nello stack, ma ogni singolo oggetto MyObject è allocato sulla memoria dinamica (heap).

Notare che abbiamo anche implementato la funzione initMyObject per inizializzare ogni membro in MyObject solo a scopo di test. La funzione restituisce -1 se il puntatore passato è null, e l’istruzione if viene inserita nel cicli for per assicurarsi che venga stampato il messaggio di errore corrispondente.

#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);
}

Tuttavia, c’è una parte errata del programma precedente che non può essere consentita in alcun codice di produzione. Il programma si chiude senza deallocare le regioni di memoria che sono state allocate dinamicamente nel bucle. Notare che, analogamente all’allocazione, ogni singolo elemento dell’array deve essere liberato. Pertanto, abbiamo implementato una funzione separata, deallocMyObjectArray, per eseguire chiamate iterative a free nel seguente esempio di codice.

#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);
}
Autore: 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

Articolo correlato - C Struct