malloc() Funktion in der C-Bibliothek mit BEISPIEL

⚡ Intelligente Zusammenfassung

malloc() in C reserviert zur Laufzeit einen Speicherblock auf dem Heap und gibt einen void-Zeiger auf dessen erstes Byte zurück, sodass Programme Speicher anfordern können, dessen Größe erst bei der tatsächlichen Ausführung des Codes bekannt wird.

  • 🧠 Laufzeitzuweisung: malloc() reserviert Speicher während der Ausführung, wenn die benötigte Größe zur Kompilierzeit nicht bekannt ist.
  • 📦 Syntax: Ein cast_type-Zeiger empfängt malloc(byte_size), wobei die Größe üblicherweise mit sizeof für die Portabilität festgelegt wird.
  • ⚠️ NULL-Prüfung: Bei einer fehlgeschlagenen Anfrage wird ein NULL-Zeiger zurückgegeben. Überprüfen Sie daher das Ergebnis, bevor Sie darauf zugreifen.
  • Zeigerarithmetik: Der Block ist zusammenhängend, daher verwenden Sie + statt ++, um auf die Array-Elemente zuzugreifen.
  • 🧹 Speicher freigeben: Um Speicherlecks und hängende Zeiger zu vermeiden, sollte jeder Speicherblock mit free() freigegeben werden.
  • 🤖 KI-Unterstützung: KI-Assistenten und GitHub Copilot entwerfen malloc()-Aufrufe und kennzeichnen fehlende free()-Anweisungen.

malloc()-Funktion in C

Was ist malloc in C?

Die Funktion malloc() steht für die Speicherzuweisung. Es handelt sich um eine Funktion, die zur dynamischen Zuweisung eines Speicherblocks verwendet wird. Es reserviert Speicherplatz der angegebenen Größe und gibt den Nullzeiger zurück, der auf den Speicherort zeigt. Der zurückgegebene Zeiger ist normalerweise vom Typ void. Das bedeutet, dass wir jedem Zeiger eine Malloc-Funktion zuweisen können.

Was ist Malloc in C?

Syntax

ptr = (cast_type *) malloc (byte_size);

Dabei steht:

  • ptr ist ein Zeiger auf cast_type.
  • Die malloc-Funktion gibt einen Zeiger auf den zugewiesenen Speicher von byte_size zurück.
Example: ptr = (int *) malloc (50)

Bei erfolgreicher Ausführung dieser Anweisung wird ein Speicherplatz von 50 Byte reserviert. Die Adresse des ersten Bytes des reservierten Speicherplatzes wird dem Zeiger ptr vom Typ int zugewiesen.

Betrachten Sie ein weiteres Beispiel einer Malloc-Implementierung:

#include <stdlib.h>
int main(){
int *ptr;
ptr = malloc(15 * sizeof(*ptr)); /* a block of 15 integers */
    if (ptr != NULL) {
      *(ptr + 5) = 480; /* assign 480 to sixth integer */
      printf("Value of the 6th integer is %d",*(ptr + 5));
    }
}

Ausgang:

Value of the 6th integer is 480

Beachten Sie, dass sizeof(*ptr) anstelle von sizeof(int) verwendet wurde, um den Code robuster zu gestalten, falls die *ptr-Deklaration später in einen anderen Datentyp umgewandelt wird.

Die Zuweisung kann fehlschlagen, wenn der Speicher nicht ausreicht. In diesem Fall wird ein NULL-Zeiger zurückgegeben. Daher sollten Sie Code einschließen, um nach einem NULL-Zeiger zu suchen.

Beachten Sie, dass der zugewiesene Speicher zusammenhängend ist und als Array behandelt werden kann. Wir können verwenden Zeiger Um auf die Array-Elemente zuzugreifen, verwenden Sie arithmetische Operationen anstelle von eckigen Klammern [ ]. Wir empfehlen, + zu verwenden, um auf Array-Elemente zu verweisen, da die Inkrementierung ++ oder += die vom Zeiger gespeicherte Adresse ändert.

Die Malloc-Funktion kann auch mit dem Zeichendatentyp sowie komplexen Datentypen wie Strukturen verwendet werden.

Warum sollte man malloc() in C verwenden?

Statische Arrays und gewöhnliche Variablen legen ihre Größe beim Kompilieren des Programms fest. Das führt zu Speicherplatzverschwendung, wenn der Bedarf geringer ist, und zu einem Fehler, wenn er größer ist. `malloc()` löst dieses Problem, indem es Speicher zur Laufzeit anfordert. So kann ein Programm einen Puffer exakt an die empfangene Datenmenge anpassen. Diese Flexibilität zur Laufzeit ist der Kern von dynamische Speicherzuordnung in C.

Die dynamische Speicherverwaltung mit malloc() ist in vielen gängigen Situationen die richtige Wahl:

  • Der Umfang der Eingabe ist erst nach dem Programmstart bekannt, beispielsweise beim Einlesen einer Datei oder einer vom Benutzer bereitgestellten Liste.
  • Es werden große Blöcke benötigt, die den begrenzten Stack überlaufen lassen würden, da malloc() vom viel größeren Heap liest.
  • Daten müssen die Funktion überdauern, die sie erzeugt hat, da der Heap-Speicher so lange bestehen bleibt, bis er explizit freigegeben wird.
  • Strukturen und Arrays müssen während der Programmausführung vergrößert oder verkleinert werden.

Da der reservierte Block als Zeiger zurückgegeben wird, kann er kostengünstig zwischen Funktionen weitergegeben werden, ohne die zugrunde liegenden Daten zu kopieren.

Wie man von malloc() reservierten Speicher freigibt

Der von `malloc()` reservierte Speicher liegt im Heap und wird nicht automatisch freigegeben. Wenn ein Programm ständig Speicher allokiert, ohne ihn freizugeben, verbraucht es nach und nach den gesamten verfügbaren Speicher – ein Fehler, der als Speicherleck bekannt ist. Die Funktion `free()` gibt einen freigegebenen Speicherblock an das System zurück, sodass der Speicherplatz wiederverwendet werden kann.

Die Funktion free() nimmt ein einzelnes Argument entgegen, den von malloc() zurückgegebenen Zeiger, und gibt den gesamten Speicherblock auf einmal frei:

int *ptr;
ptr = malloc(10 * sizeof(int));
if (ptr != NULL) {
    /* use the allocated memory here */
    free(ptr);   /* release the block */
    ptr = NULL;  /* avoid a dangling pointer */
}

Befolgen Sie diese Regeln, um dynamischen Speicher sicher zu verwalten:

  • Rufen Sie free() genau einmal für jede erfolgreiche malloc()-Aufrufe auf; das zweimalige Freigeben desselben Speicherblocks führt zu undefiniertem Verhalten.
  • Setzen Sie den Zeiger nach der Freigabe auf NULL, damit er nicht als hängender Zeiger wiederverwendet werden kann.
  • Verwenden Sie niemals free() für einen Zeiger, den malloc() nicht zurückgegeben hat, einschließlich eines Zeigers, der durch Zeigerarithmetik verschoben wurde.
  • Jede Speicherbelegung muss mit einer entsprechenden Freigabe abgeglichen werden, bevor der Zeiger seinen Gültigkeitsbereich verlässt.

Keeping Das ausgewogene Zuweisen und Freigeben von Speicher ist die Kerndisziplin der manuellen Speicherverwaltung in C und verhindert sowohl Speicherlecks als auch Abstürze, die durch die Wiederverwendung freigegebenen Speichers verursacht werden.

malloc() vs calloc(): Wichtigste Unterschiede

malloc() und calloc() Beide Funktionen reservieren Heap-Speicher, unterscheiden sich aber in ihren Argumenten und in der Behandlung des neu reservierten Speicherblocks. `malloc()` benötigt ein Argument, die Gesamtanzahl der Bytes, und initialisiert den Block nicht, sodass er unvorhersehbare Werte enthält, bis das Programm darauf schreibt. `calloc()` hingegen benötigt zwei Argumente, die Anzahl der Elemente und deren Größe, und überschreibt alle Bytes mit Nullen, bevor der Zeiger zurückgegeben wird.

Die praktischen Unterschiede lassen sich auf drei Punkte reduzieren:

  • Initialisierung: calloc() setzt den Speicher auf Null, malloc() hingegen nicht, was malloc() etwas schneller macht, wenn die Werte ohnehin überschrieben werden.
  • Argumente: Man schreibt malloc(n * size), aber calloc(n, size), um dasselbe Array zu reservieren.
  • Anwendungsfall: Wählen Sie calloc(), wenn ein sauberer, mit Nullen initialisierter Block wichtig ist, und malloc(), wenn Geschwindigkeit im Vordergrund steht und die Initialisierung manuell erfolgt.

Beide Funktionen sind in stdlib.h deklariert, beide geben im Fehlerfall einen void-Zeiger oder NULL zurück und beide geben ihren Speicher mit der gleichen free()-Funktion zurück.

Häufig gestellte Fragen

In C ist die Typumwandlung optional und oft nicht empfehlenswert, da void* automatisch in jeden Objektzeiger konvertiert wird und eine explizite Typumwandlung eine fehlende Einbindung von stdlib.h verschleiern kann. C++Allerdings wird die Besetzung benötigt.

Ein Rückgabewert von NULL bedeutet, dass die Anfrage fehlgeschlagen ist, üblicherweise aufgrund von Speichermangel. Überprüfen Sie den Zeiger immer, bevor Sie ihn verwenden, da das Dereferenzieren von NULL zu undefiniertem Verhalten führt und in der Regel einen Programmabsturz verursacht.

realloc() ändert die Größe eines zuvor mit malloc() reservierten Speicherblocks.ping Die vorhandenen Daten werden bis zur kleineren Größe gespeichert. Schlägt dies fehl, wird NULL zurückgegeben und der ursprüngliche Datenblock bleibt unverändert. Daher sollte das Ergebnis zunächst einem temporären Zeiger zugewiesen werden.

Ein Speicherleck entsteht, wenn der durch malloc() erzeugte Heap-Speicher nicht mit free() freigegeben wird. Das Programm reserviert weiterhin Speicherplatz, den es nicht mehr benötigt, wodurch der verfügbare Speicher allmählich erschöpft wird.

malloc() reserviert Speicher auf dem Heap, nicht auf dem Stack. Heap-Blöcke bleiben gültig, bis free() aufgerufen wird; sie können also die Funktion überdauern, die sie erzeugt hat, im Gegensatz zu automatischen Stack-Variablen, die nach der Rückgabe verschwinden.

malloc() ist eine Bibliotheksfunktion, die void* zurückgibt und sizeof benötigt, um Bytes zu berechnen. C++ Der Operator `new` gibt einen typisierten Zeiger zurück und ruft Konstruktoren auf. Verwenden Sie `malloc()` zusammen mit `free()` und `new` zusammen mit `delete`.

Ja. KI-Programmierassistenten entwerfen malloc()-Aufrufe, fügen NULL-Prüfungen ein und markieren fehlende free()-Aufrufe oder Speicherlecks. Außerdem können sie Zeigerarithmetik erklären. Kompilieren und testen Sie den generierten Code immer, bevor Sie ihm vertrauen.

GitHub-Copilot schlägt malloc(), sizeof() und passende free()-Zeilen aus einem Kommentar vor, der Ihre Absicht beschreibt. RevPrüfen Sie vor dem Kompilieren jeden Vorschlag auf fehlende NULL-Prüfungen und Speicherlecks.

Fassen Sie diesen Beitrag mit folgenden Worten zusammen: