Kann man anrufen free()
irgendwie scheitern?
Zum Beispiel:
free(NULL);
Taichman
Kann man anrufen free()
irgendwie scheitern?
Zum Beispiel:
free(NULL);
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 wirdptr
freigegeben werden, d. h. für eine weitere Zuweisung verfügbar gemacht werden. Wennptr
ein Nullzeiger ist, findet keine Aktion statt. Andernfalls, wenn das Argument nicht mit einem zuvor von der zurückgegebenen Zeiger übereinstimmtcalloc
,malloc
oderrealloc
-Funktion oder wenn der Speicherplatz durch einen Aufruf von freigegeben wurdefree
oderrealloc
ist 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 void
der 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
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.
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()
.