Geschichte der Frage:
Die Mechanismen der dynamischen Speicherzuweisung erschienen in C zusammen mit den Funktionen der Standardbibliothek malloc/free in <stdlib.h>. Sie ermöglichten die Implementierung von variabel großen Strukturen, komplexen Sammlungen und Objekten, was einen starken Impuls für die Entwicklung der Sprache und deren Anwendung in der großen Programmierung gab.
Problem:
Die Arbeit mit dynamischem Speicher erfordert vom Programmierer die vollständige Kontrolle über den Lebenszyklus der Objekte. Fehler (Speicherlecks, doppelte Freigabe, falsche Verwendung von Zeigern) können zu Abstürzen oder Schwachstellen führen (zum Beispiel zu Exploits durch den Fehler use-after-free).
Lösung:
— Überprüfen Sie immer die Rückgabewerte von malloc/calloc/realloc. Wenn die Zuweisung fehlschlägt, geben sie NULL zurück. — Bei der Freigabe des Speichers den Zeiger auf NULL setzen, um die Verwendung des freigegebenen Blocks zu vermeiden. — Verwenden Sie den Zeiger nach free nicht mehr. — Achten Sie auf die korrekte Zuordnung von malloc/free und calloc/free.
Beispielcode:
#include <stdio.h> #include <stdlib.h> int main() { int *arr = malloc(5 * sizeof(int)); if (!arr) { perror("Speicher konnte nicht zugewiesen werden"); return 1; } for (int i = 0; i < 5; ++i) arr[i] = i * i; for (int i = 0; i < 5; ++i) printf("%d ", arr[i]); printf(" "); free(arr); arr = NULL; return 0; }
Wichtige Merkmale:
Was passiert, wenn Sie Speicher, der über malloc zugewiesen wurde, mit dem Operator delete freigeben oder umgekehrt (in C++)?
Sie dürfen die Mechanismen zur Speicherzuweisung und -freigabe zwischen den Sprachen (C/C++) nicht vermischen. In C sind es nur malloc/free, in C++ new/delete.
Was passiert, wenn Sie versuchen, free(NULL) aufzurufen?
free(NULL) ist sicher (das ist im C-Standard garantiert). Dieser Aufruf macht nichts.
Kann realloc verwendet werden, um einen Speicherblock zu vergrößern oder zu verkleinern, und was passiert mit dem ursprünglichen Zeiger?
realloc kann den Speicherblock verschieben, und wenn dies geschieht, wird der alte Zeiger ungültig. Weisen Sie immer den neuen Zeiger zu:
ptr = realloc(ptr, new_size);
Speicher für ein Array in einer Schleife zugewiesen, aber am Ende der Iteration vergessen, ihn freizugeben. Über Nacht hat das Programm auf dem Server den gesamten RAM "aufgefressen".
Vorteile:
Nachteile:
In der Schleife wurde der Speicher stets nach der Verwendung freigegeben, alle NULL-Prüfungen wurden sofort nach malloc durchgeführt, und es wurden Debugging-Tools zur Überwachung von Lecks verwendet.
Vorteile:
Nachteile: