Beschädigt free(ptr), wobei ptr NULL ist, den Speicher?

Lesezeit: 6 Minuten

Vijays Benutzeravatar
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 ptr ist 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

Benutzeravatar von Gregory Pakosz
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.

Sehen ISO-IEC 9899.

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.

    – R. Samuel Klatschko

    21. Dezember 2009 um 17:51 Uhr

  • @Tomas 3BSD (winehq.org/pipermail/wine-patches/2006-October/031544.html) und PalmOS für zwei (2. Hand für beide).

    – Douglas Leder

    11. März 2010 um 14:04 Uhr


  • @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.

Benutzeravatar von Prasoon Saurav
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.

Benutzeravatar von stefanB
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

1423910cookie-checkBeschädigt free(ptr), wobei ptr NULL ist, den Speicher?

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

Privacy policy