Beschädigt free(ptr), wobei ptr NULL ist, den Speicher?
Lesezeit: 6 Minuten
Vijay
Theoretisch kann ich das sagen
free(ptr);
free(ptr);
ist eine Speicherbeschädigung, da wir den bereits freigegebenen Speicher freigeben.
Aber was wenn
free(ptr);
ptr=NULL;
free(ptr);
Da sich das Betriebssystem undefiniert verhält, kann ich keine tatsächliche theoretische Analyse darüber erhalten, was passiert. Was auch immer ich tue, ist diese Speicherbeschädigung oder nicht?
Ist das Freigeben eines NULL-Zeigers gültig?
Ich bin mir nicht sicher über den freien C-Standard, aber in C++ ist delete(NULL) vollkommen gültig, daher sollte es meiner Meinung nach auch free(NULL) sein.
– Priyank Bolia
21. Dezember 2009 um 7:47 Uhr
@Pryank: delete NULL ist in C++ nicht gültig. delete kann auf Nullzeigerwerte konkreten Typs angewendet werden, aber nicht auf NULL. delete (int*) NULL ist legal, aber nicht delete NULL.
– AnT steht zu Russland
21. Dezember 2009 um 7:53 Uhr
Das heißt, wenn ein Zeiger auf NULL zeigt, führt free nichts aus. Bedeutet das !!!!!! Jedes Mal, wenn wir in unserer Codierung einen Speicher freigeben möchten, kann einfach ein free(ptr) durch ptr=NULL ersetzt werden?
– Vijay
21. Dezember 2009 um 8:04 Uhr
Nein. Wenn ptr weist auf die Erinnerung hin, und du rufst nicht an free darauf, dann wird der Speicher auslaufen. Einstellen auf NULL verliert einfach den Zugriff auf den Speicher und leckt. Wenn die ptrist zufälligerweise NULLanrufen free ist ein No-Operations.
– GManNickG
21. Dezember 2009 um 8:05 Uhr
@benjamin: Hä? Was hat Sie zu dem Schluss gebracht, dass Sie ersetzen können free(ptr) mit ptr = NULL. Niemand hat so etwas gesagt.
– AnT steht zu Russland
21. Dezember 2009 um 8:07 Uhr
Gregor Pakosz
7.20.3.2 Die free Funktion
Zusammenfassung
#include <stdlib.h>
void free(void *ptr);
Beschreibung
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.
Abgesehen davon, wenn Sie sich verschiedene Codebasen in freier Wildbahn ansehen, werden Sie feststellen, dass die Leute manchmal Folgendes tun:
if (ptr)
free(ptr);
Dies liegt daran, dass einige C-Laufzeitumgebungen (ich erinnere mich sicher, dass dies unter PalmOS der Fall war) beim Freigeben von a abstürzten NULL Zeiger.
Aber heutzutage glaube ich, dass man davon ausgehen kann free(NULL) ist ein Nop gemäß den Anweisungen des Standards.
Nein, ptr=NULL ist keinesfalls ein Ersatz für free(ptr), beides ist völlig unterschiedlich
– Prasun Saurav
21. Dezember 2009 um 8:05 Uhr
NEIN, heißt es free(ptr) wo ptr ist null hat keine Nebenwirkungen. Aber auf jeden Fall wird jeder Speicher belegt malloc() oder calloc() muss anschließend mit freigegeben werden free()
– Gregory Pakosz
21. Dezember 2009 um 8:06 Uhr
ptr=NULL stellt sicher, dass, selbst wenn Sie versehentlich free(ptr) aufrufen, Ihr Programm nicht segfault.
– Prasun Saurav
21. Dezember 2009 um 8:06 Uhr
Bitte beachten Sie, dass, obwohl der C-Standard sagt, dass es sich um eine No-Op handelt, das nicht bedeutet, dass jede C-Bibliothek so damit umgeht. Ich habe kostenlose Abstürze (NULL) gesehen, daher ist es am besten, den kostenlosen Aufruf von vornherein zu vermeiden.
– Derick
24. Januar 2013 um 9:43 Uhr
@WereWolfBoy er meint vermeiden free(NULL) durch Testen des Zeigers gegen NULL vor dem Anruf free()
– Gregory Pakosz
25. April 2013 um 13:32 Uhr
Alle standardkonformen Versionen der C-Bibliothek behandeln free(NULL) als no-op.
Allerdings gab es früher einige Versionen von free, die bei free(NULL) abstürzten, weshalb Sie möglicherweise einige defensive Programmiertechniken empfehlen:
if (ptr != NULL)
free(ptr);
-1 [citation needed]. Das Ändern des Codestils aufgrund einer Theorie einer archaischen Hörensagen-Implementierung ist eine schlechte Idee.
– Thomas
21. Dezember 2009 um 14:02 Uhr
@Tomas – Ich habe nie empfohlen, den Stil zu ändern, ich habe einfach erklärt, warum Sie diese Empfehlung möglicherweise immer noch in einigen Stilen sehen.
@Tomas: Das Problem lag in Dingen wie Version 7 Unix. Als ich lernte, war free(xyz) wo xyz == NULL ein Rezept für eine sofortige Katastrophe auf der Maschine, auf der ich lernte (ICL Perq mit PNX, das auf Version 7 Unix mit einigen System III-Extras basierte). Aber so habe ich schon lange nicht mehr codiert.
– Jonathan Leffler
11. März 2010 um 14:06 Uhr
Netware stürzt auch beim Freigeben von NULL ab … (habe gerade einen Absturz darauf debuggt …)
– Kalmarius
22. Oktober 2013 um 10:26 Uhr
Wenn ptr NULL ist, wird keine Operation ausgeführt.
sagt die Dokumentation.
Meinst du, dass Free nichts ausführt?
– Vijay
21. Dezember 2009 um 7:48 Uhr
Benjamin, genau das bedeutet es. Was würden Sie erwarten, wenn es sich der Nichtigkeit des Arguments bewusst ist?
– Michael Krelin – Hacker
21. Dezember 2009 um 7:52 Uhr
Ich erinnere mich, wo ich an PalmOS gearbeitet habe free(NULL) abgestürzt.
Prasun Saurav
free(ptr);
ptr=NULL;
free(ptr);/*This is perfectly safe */
Sie können einen NULL-Zeiger sicher löschen. In diesem Fall wird keine Operation ausgeführt. Mit anderen Worten, free() macht nichts mit einem NULL-Zeiger.
stefanB
Empfohlene Verwendung:
free(ptr);
ptr = NULL;
Sehen:
man free
The free() function deallocates the memory allocation pointed to by ptr.
If ptr is a NULL pointer, no operation is performed.
Wenn Sie den Zeiger auf setzen NULL nach free() Du kannst anrufen free() erneut darauf und es wird kein Vorgang ausgeführt.
free(NULL) ist sowohl in C als auch vollkommen legal delete (void *)0 und delete[] (void *)0 sind in C++ erlaubt.
Übrigens, das zweimalige Freigeben von Speicher verursacht normalerweise eine Art Laufzeitfehler, sodass nichts beschädigt wird.
delete 0 ist in C++ nicht erlaubt. delete erfordert explizit einen Ausdruck vom Typ Zeiger. Es ist legal, sich zu bewerben delete auf einen typisierten Nullzeigerwert, aber nicht auf 0 (und nicht zu NULL).
– AnT steht zu Russland
21. Dezember 2009 um 7:49 Uhr
Sie können nicht löschen void* entweder 😛 Welche Destruktoren soll es ausführen?
– GManNickG
21. Dezember 2009 um 8:00 Uhr
@GMan: Du kann löschen void * solange es ein Nullzeiger ist.
– AnT steht zu Russland
21. Dezember 2009 um 8:02 Uhr
OK Fair genug. Ich habe vergessen, dass wir uns nur speziell mit null befassen.
– GManNickG
21. Dezember 2009 um 8:07 Uhr
beschädigt normalerweise nichts, ist aber nicht garantiert. ASLR macht dies eher unwahrscheinlich, aber immer noch nicht unmöglich: buf1=malloc(X); free(buf1);buf2=malloc(X);free(buf1); – Wenn Sie Pech haben, hat buf2 hier genau dieselbe Adresse wie buf1, und Sie haben buf1 versehentlich zweimal befreit, also haben Sie beim 2. Freigeben von buf1 tatsächlich buf2 stillschweigend befreit, ohne einen (unmittelbaren) Fehler / Absturz / was auch immer zu verursachen. (Aber Sie werden wahrscheinlich trotzdem das nächste Mal abstürzen, wenn Sie versuchen, buf2 zu verwenden – und dieses Szenario ist sehr unwahrscheinlich, wenn Sie auf ASLR laufen.)
– Hansenrik
17. September 2018 um 15:19 Uhr
14239100cookie-checkBeschädigt free(ptr), wobei ptr NULL ist, den Speicher?yes
Ich bin mir nicht sicher über den freien C-Standard, aber in C++ ist delete(NULL) vollkommen gültig, daher sollte es meiner Meinung nach auch free(NULL) sein.
– Priyank Bolia
21. Dezember 2009 um 7:47 Uhr
@Pryank:
delete NULL
ist in C++ nicht gültig. delete kann auf Nullzeigerwerte konkreten Typs angewendet werden, aber nicht aufNULL
.delete (int*) NULL
ist legal, aber nichtdelete NULL
.– AnT steht zu Russland
21. Dezember 2009 um 7:53 Uhr
Das heißt, wenn ein Zeiger auf NULL zeigt, führt free nichts aus. Bedeutet das !!!!!! Jedes Mal, wenn wir in unserer Codierung einen Speicher freigeben möchten, kann einfach ein free(ptr) durch ptr=NULL ersetzt werden?
– Vijay
21. Dezember 2009 um 8:04 Uhr
Nein. Wenn
ptr
weist auf die Erinnerung hin, und du rufst nicht anfree
darauf, dann wird der Speicher auslaufen. Einstellen aufNULL
verliert einfach den Zugriff auf den Speicher und leckt. Wenn dieptr
ist zufälligerweiseNULL
anrufenfree
ist ein No-Operations.– GManNickG
21. Dezember 2009 um 8:05 Uhr
@benjamin: Hä? Was hat Sie zu dem Schluss gebracht, dass Sie ersetzen können
free(ptr)
mitptr = NULL
. Niemand hat so etwas gesagt.– AnT steht zu Russland
21. Dezember 2009 um 8:07 Uhr