Kann ein Aufruf von free() in C jemals fehlschlagen?

Lesezeit: 2 Minuten

Benutzer-Avatar
Taichman

Kann man anrufen free() irgendwie scheitern?

Zum Beispiel:

free(NULL);

Benutzer-Avatar
E. Benoît

Das Freigeben eines NULL-Zeigers kann nicht fehlschlagen. Und free gibt keinen Fehler zurück, aber das Freigeben von nicht zugewiesenem Speicher, bereits freigegebenem Speicher oder der Mitte eines zugewiesenen Blocks ist ein undefiniertes Verhalten – es kann einen Speicherfehler verursachen und das Programm kann abbrechen (oder schlimmer noch, es wird die Heap-Struktur beschädigen und später abstürzen ).

Oder, noch schlimmer, laufen Sie weiter, beschädigen aber Ihre Daten und schreiben sie auf die Festplatte, ohne dass Sie es merken 🙂

Der relevante Teil des Standards (C99) ist Abschnitt 7.20.3.2:

#include <stdlib.h>
void free(void *ptr);

Das free Funktion verursacht das Leerzeichen, auf das von gezeigt wird ptr freigegeben werden, d. h. für eine weitere Zuweisung verfügbar gemacht werden. Wenn ptr ein Nullzeiger ist, findet keine Aktion statt. Andernfalls, wenn das Argument nicht mit einem zuvor von der zurückgegebenen Zeiger übereinstimmt calloc, mallocoder realloc -Funktion oder wenn der Speicherplatz durch einen Aufruf von freigegeben wurde free oder reallocist das Verhalten undefiniert.

Das free Funktion gibt keinen Wert zurück.

  • Nicht will cause, may cause. Das wirklich Ärgerliche an undefiniertem Verhalten ist, dass es manchmal funktioniert.

    – paxdiablo

    15. März 2011 um 7:43 Uhr


  • @paxdiablo: Nein, das wirklich Ärgerliche ist, dass es oft dauerhaft auf einer weit verbreiteten Plattform funktioniert, also gibt es eine Unmenge von Entwicklern, die glauben, dass es in Ordnung ist, weil “sie es schon seit Ewigkeiten tun”.

    – scharfer Zahn

    15. März 2011 um 7:48 Uhr

  • +1 zur Unterscheidung zwischen “Fehler” und undefiniertem Verhalten. Sie haben Recht, kostenlos hat keine Fehlerfälle. Ungültige Eingaben, die UB verursachen, sind eine separate Sache.

    – Steve Jessop

    15. März 2011 um 10:04 Uhr

free(NULL) tut nichts; free auf einem Zeiger, der nicht mit demselben Allokator belegt wurde (malloc, calloc, usw.) oder bereits freigegeben wurde, ist undefiniert. Seit free kehrt zurück voidder einzige Weg, wie es fehlschlagen kann, ist ein Absturz (z. B. segfault).

Es sei denn, Sie rufen undefiniertes Verhalten auf (wie “double-free” oder versuchen es free() ein String-Literal) free() kann nicht scheitern.

Ja, es kann in mehreren Situationen fehlschlagen. Z.B

  1. Sie geben etwas frei, das nicht dynamisch zugewiesen wurde, z. B. Variablen auf dem Stapel
  2. Sie weisen einen Zeiger zu und versuchen, Zeiger + 1 freizugeben

free(NULL);

Der Aufruf von free() mit einem Nullzeiger ist erlaubt und führt zu keinem Fehler – Siehe: free() – Offene Gruppe

Das Aufrufen von frei mit einem zuvor freigegebenen Zeiger wird normalerweise eine Segmentverletzung verursachen und Ihr Programm wird beendet.

Benutzer-Avatar
Jamal

Je nach Ausführung, free() könnte fehlschlagen, wenn eine Speicherbeschädigung vorliegt, wie z. B. hier:

char *p = malloc(1000);
*(p-1)=7;
free(p);

Obwohl dies ein erfundenes Beispiel ist, können ähnliche Dinge passieren, wenn das Ende oder der Anfang eines Arrays ausgeführt wird. Das erste, was Sie vielleicht davon wissen, ist ein Schutzfehler in free().

1351800cookie-checkKann ein Aufruf von free() in C jemals fehlschlagen?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy