Dynamische Speicherallokation in C: malloc, calloc, realloc & free meistern
Dynamische Speicherallokation in C
Dieser Leitfaden führt Sie durch die dynamische Speicherallokation in C mithilfe der Standardbibliotheksfunktionen malloc(), calloc(), realloc() und free(), mit klaren Beispielen und Best-Practice-Tipps.
Warum dynamische Allokation nutzen?
Statische Arrays haben eine zur Kompilierzeit festgelegte Größe, was zu verschwendetem Speicher oder unzureichender Kapazität zur Laufzeit führen kann. Dynamische Allokation ermöglicht es Ihnen, genau die benötigte Speichermenge anzufordern, während das Programm läuft.
Alle vier Funktionen sind im Header <stdlib.h> definiert und bieten eine kontrollierte Möglichkeit, Heap-Speicher zu verwalten.
malloc() – Block von Bytes allokieren
Der Name malloc steht für "memory allocation". Er reserviert einen zusammenhängenden Speicherblock der angegebenen Größe (in Bytes) und gibt einen Zeiger vom Typ void * zurück, der in jeden anderen Zeigertyp umgewandelt werden kann.
Syntax
ptr = malloc(size_in_bytes); // bei Bedarf in gewünschten Typ casten
Beispiel
float *ptr = malloc(100 * sizeof(float)); // 400 Bytes auf den meisten Systemen
Hier zeigt ptr auf das erste Byte eines 400-Byte-Blocks. Schlägt die Anfrage fehl, gibt malloc NULL zurück. Es wird empfohlen, unnötige Casts in C zu vermeiden; der Compiler kann den Typ ableiten, wenn Sie das Ergebnis einem typisierten Zeiger zuweisen.
calloc() – Allokieren und null-initialisieren
calloc steht für "contiguous allocation". Im Gegensatz zu malloc initialisiert es jedes Bit des allokierten Blocks mit Null, was es für numerische Typen und Zeiger sicher macht.
Syntax
ptr = calloc(num_elements, size_of_each_element);
Beispiel
float *ptr = calloc(25, sizeof(float)); // 25 null-initialisierte float-Elemente
Der zurückgegebene Zeiger ist NULL, falls die Allokation fehlschlägt.
free() – Allokierten Speicher freigeben
Mit malloc oder calloc erhaltener Speicher bleibt bestehen, bis Sie ihn explizit freigeben. free() gibt den Block frei und gibt den Speicher an den Heap für zukünftige Wiederverwendung zurück.
Syntax
free(ptr);
Der Aufruf von free auf einem NULL-Zeiger ist sicher und bewirkt nichts.
Beispiel 1: malloc() und free() verwenden
#include <stdio.h>
#include <stdlib.h>
int main(void) {
int n, i, *ptr, sum = 0;
printf("Enter number of elements: ");
scanf("%d", &n);
ptr = malloc(n * sizeof(int));
if (!ptr) {
fprintf(stderr, "Error: memory not allocated.\n");
return EXIT_FAILURE;
}
printf("Enter elements: ");
for (i = 0; i < n; ++i) {
scanf("%d", ptr + i);
sum += *(ptr + i);
}
printf("Sum = %d\n", sum);
free(ptr);
return EXIT_SUCCESS;
}
Ausgabe
Enter number of elements: 3
Enter elements: 100 20 36
Sum = 156
Beispiel 2: calloc() und free() verwenden
#include <stdio.h>
#include <stdlib.h>
int main(void) {
int n, i, *ptr, sum = 0;
printf("Enter number of elements: ");
scanf("%d", &n);
ptr = calloc(n, sizeof(int));
if (!ptr) {
fprintf(stderr, "Error: memory not allocated.\n");
return EXIT_FAILURE;
}
printf("Enter elements: ");
for (i = 0; i < n; ++i) {
scanf("%d", ptr + i);
sum += *(ptr + i);
}
printf("Sum = %d\n", sum);
free(ptr);
return EXIT_SUCCESS;
}
Ausgabe
Enter number of elements: 3
Enter elements: 100 20 36
Sum = 156
realloc() – Bestehende Allokation vergrößern/verkleinern
Wenn Sie feststellen, dass Ihre aktuelle Allokation zu klein oder größer als nötig ist, passt realloc() die Größe an und bewahrt dabei die bestehenden Daten (bis zur neuen Größe).
Syntax
ptr = realloc(ptr, new_size_in_bytes);
Es gibt einen Zeiger auf den neu allokierten Block oder NULL bei Fehlschlag zurück. Um Speicherlecks zu vermeiden, speichern Sie das Ergebnis zunächst in einem temporären Zeiger.
Beispiel 3: realloc() verwenden
#include <stdio.h>
#include <stdlib.h>
int main(void) {
int *ptr, i, n1, n2;
printf("Enter initial size: ");
scanf("%d", &n1);
ptr = malloc(n1 * sizeof(int));
if (!ptr) {
fprintf(stderr, "Allocation failed.\n");
return EXIT_FAILURE;
}
printf("Addresses before reallocation:\n");
for (i = 0; i < n1; ++i) printf("%p\n", ptr + i);
printf("\nEnter new size: ");
scanf("%d", &n2);
int *tmp = realloc(ptr, n2 * sizeof(int));
if (!tmp) {
fprintf(stderr, "Reallocation failed.\n");
free(ptr);
return EXIT_FAILURE;
}
ptr = tmp;
printf("Addresses after reallocation:\n");
for (i = 0; i < n2; ++i) printf("%p\n", ptr + i);
free(ptr);
return EXIT_SUCCESS;
}
Typische Ausgabe
Enter initial size: 2
Addresses before reallocation:
0x7ffc12345670
0x7ffc12345674
Enter new size: 4
Addresses after reallocation:
0x7ffc12345670
0x7ffc12345674
0x7ffc12345678
0x7ffc1234567c
Durch die Beherrschung dieser vier Funktionen und die Anwendung proper Fehlerbehandlung können Sie Heap-Speicher in jeder C-Anwendung sicher und effizient verwalten.
C Sprache
- ROM, PROM, EPROM und EEPROM verstehen: Design, Programmierung und Identifikation
- Mikroprozessoren: Die Evolution des Stored-Program-Computing
- C++ Speicherverwaltung meistern: Experten-Einsatz von new und delete
- Cervoz bringt DDR4-2666 Speicher für industrielle KI- und IoT-Lösungen
- C++ Dynamische Array‑Allokation: Praktischer Leitfaden mit Code‑Beispielen
- calloc() in C: Null-initialisierte Speicherallokation mit praktischem Beispiel
- realloc() in C: Syntax, Best Practices & Beispiel
- Dynamische Speicherverwaltung in C: calloc, malloc und free erklärt
- Dynamische Preisgestaltung kehrt in den stationären Handel zurück: Warum sie unvermeidlich ist
- C++ Dynamischer Speicher: Stack vs. Heap erklärt