Struct-Speicher mit malloc in C allozieren

Jinku Hu 12 Oktober 2023
  1. Verwenden Sie malloc mit dem sizeof-Operator, um Strukturspeicher in C zu allokieren
  2. Verwenden Sie die for-Schleife, um Speicher für ein Array von Strukturen in C zu allozieren
Struct-Speicher mit malloc in C allozieren

Dieser Artikel erklärt verschiedene Methoden, wie man mit malloc in C Strukturspeicher allokieren kann.

Verwenden Sie malloc mit dem sizeof-Operator, um Strukturspeicher in C zu allokieren

malloc ist die Kernfunktion für die dynamische Speicherzuweisung in C, die ein einzelnes Integer-Argument für die Anzahl der zuzuweisenden Bytes annimmt. Um den Speicher des definierten benutzerdefinierten struct-Objekts zu allokieren, sollten wir den sizeof-Operator aufrufen und die Menge an Speicher abrufen, die das Objekt benötigt, um gespeichert zu werden.

Beachten Sie, dass wir den Ausdruck sizeof(MyObject) direkt als Argument an den malloc-Aufruf übergeben können. Ein Nachteil von malloc ist, dass erfolgreich zugewiesener Speicher nicht initialisiert wird, d.h. es können einige Garbage-Werte gespeichert sein. Um diesem Problem entgegenzuwirken, bietet die C-Bibliothek eine weitere nützliche Funktion - calloc, um den Speicherbereich automatisch mit Null zu initialisieren. Das folgende Beispiel zeigt die Speicherzuweisung für die einzelne struct 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);
}

Verwenden Sie die for-Schleife, um Speicher für ein Array von Strukturen in C zu allozieren

Es ist oft sinnvoll, ein Array von Strukturen zu deklarieren, das einen größeren Speicherbereich benötigt, als auf dem Stack verfügbar ist. Daher müssen wir das Array als dynamischen Speicher allokieren. Der folgende Beispielcode demonstriert den Fall, dass das Array mit 100 Zeigern auf die MyObject-Strukturen auf dem Stack deklariert wird, aber jedes einzelne MyObject-Objekt im dynamischen Speicher (Heap) alloziert wird.

Beachten Sie, dass wir auch die Funktion initMyObject implementiert haben, um jedes Mitglied im MyObject nur zu Testzwecken zu initialisieren. Die Funktion gibt -1 zurück, wenn der übergebene Zeiger null ist, und die if-Anweisung wird in die for-Schleife gestellt, um sicherzustellen, dass die entsprechende Fehlermeldung ausgegeben wird.

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

Allerdings gibt es einen fehlerhaften Teil des vorherigen Programms, der in keinem Seriencode erlaubt sein kann. Das Programm wird beendet, ohne dass Speicherbereiche, die in der Schleife dynamisch alloziert wurden, wieder freigegeben werden. Beachten Sie, dass, ähnlich wie bei der Allokation, jedes einzelne Element des Arrays wieder freigegeben werden muss. Daher haben wir im folgenden Codebeispiel eine eigene Funktion, deallocMyObjectArray, implementiert, um iterative Aufrufe von free auszuführen.

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

Verwandter Artikel - C Struct