Wie verwende ich dynamische Speicherzuweisung mit malloc und free richtig?
- Einführung in die dynamische Speicherzuweisung
- Verwendung von malloc
- Speicherinitialisierung
- Speicherfreigabe mit free
- Zusammenfassung eines korrekten Ablaufs
- Beispielcode
Einführung in die dynamische Speicherzuweisung
In der Programmiersprache C ist die dynamische Speicherzuweisung ein zentrales Konzept, das es ermöglicht, während der Programmlaufzeit Speicherbereiche flexibel zu reservieren. Dies unterscheidet sich von statischer oder automatischer Speicherzuweisung, bei denen Speicher zur Kompilierzeit oder beim Eintritt in einen Funktionsblock reserviert wird. Die wichtigsten Funktionen für die dynamische Speicherverwaltung sind malloc (memory allocation) und free (zum Freigeben des Speichers).
Verwendung von malloc
Die Funktion malloc reserviert einen zusammenhängenden Speicherblock auf dem sogenannten Heap mit einer angegebenen Größe in Bytes. Der Rückgabewert ist ein Zeiger vom Typ void *, der auf den Anfang des reservierten Bereichs zeigt. Da void * kein konkreter Datentyp ist, wird dieser Zeiger normalerweise in einen passenden Typ gecastet. Ein typisches Beispiel ist die Reservierung eines Speicherbereichs für ein Array von Integern:
int *array = (int *) malloc(n * sizeof(int));Hierbei steht n für die Anzahl der Elemente. Es ist wichtig, die Rückgabe von malloc auf NULL zu prüfen, denn im Fehlerfall (z.B. wenn nicht genügend Speicher verfügbar ist) liefert malloc NULL zurück. Wird dieser Fall nicht abgefangen, kann es zu undefiniertem Verhalten kommen, wenn versucht wird, über den Zeiger zuzugreifen.
Speicherinitialisierung
Die von malloc reservierten Speicherbereiche haben einen undefinierten Inhalt. Wenn es wichtig ist, dass der Speicher mit Nullen oder einem definierten Wert initialisiert wird, kann man entweder den Speicher manuell mit einer for-Schleife füllen oder die Funktion calloc (contiguous allocation) verwenden, die automatisch auf Null initialisiert.
Speicherfreigabe mit free
Jeder Speicherbereich, der mit malloc (oder calloc bzw. realloc) reserviert wurde, muss nach Gebrauch mit free wieder freigegeben werden. Die Funktion free nimmt als Argument den Zeiger auf den Anfang des Speicherbereichs entgegen. Wird der Speicher nicht freigegeben, entstehen Speicherlecks, die langfristig den Speicherverbrauch erhöhen und zum Absturz führen können.
Ein Beispiel für die korrekte Freigabe:
free(array);array = NULL; // Optional: Zeiger auf NULL setzen, um Dangling Pointer zu vermeidenEs ist außerdem wichtig, niemals mehrfach denselben Speicherbereich mit free freizugeben oder auf einen bereits freigegebenen Bereich zuzugreifen, da dies zu undefiniertem Verhalten führt.
Zusammenfassung eines korrekten Ablaufs
Der typische Ablauf beim Einsatz dynamischer Speicherzuweisung sieht folgendermaßen aus: Zuerst wird mit malloc eine Speicherblock reserviert, die Rückgabe wird auf NULL geprüft, anschließend wird der Speicher genutzt (z.B. mit Daten befüllt) und am Ende des Programms oder wenn der Speicher nicht mehr benötigt wird, wird dieser mit free freigegeben. Optional kann der Zeiger nach dem free auf NULL gesetzt werden, um versehentliche Zugriffe zu vermeiden.
Beispielcode
#include <stdio.h>#include <stdlib.h>int main() { int n = 5; int *array = (int *) malloc(n * sizeof(int)); if (array == NULL) { printf("Speicherreservierung fehlgeschlagen.\n"); return 1; } for (int i = 0; i < n; i++) { array = i * i; // Array mit Quadratzahlen füllen } for (int i = 0; i < n; i++) { printf("array = %d\n", i, array ); } free(array); array = NULL; return 0;}
Dieses Beispiel zeigt die korrekte Verwendung von malloc und free: Es wird dynamischer Speicher für 5 Integer reserviert, der Inhalt befüllt und ausgegeben. Anschließend wird der Speicher wieder freigegeben.
