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 das Gedächtnisbeschädigung oder nicht?
Ist das Freigeben eines NULL-Zeigers gültig?
delete NULL
ist in C ++ nicht gültig. delete kann auf Nullzeigerwerte vom konkreten Typ angewendet werden, nicht jedoch aufNULL
.delete (int*) NULL
ist legal, aber nichtdelete NULL
.ptr
auf den Speicher zeigen und ihn nicht aufrufenfree
, geht der Speicher verloren. Wenn Sie esNULL
so einstellen, dass es nur den Speicher im Griff hat und undicht wird. Wennptr
dies der FallNULL
ist,free
ist das Aufrufen kein Vorgang.free(ptr)
mitptr = NULL
. Niemand sagte so etwas.Antworten:
Siehe ISO-IEC 9899 .
Wenn Sie sich jedoch verschiedene Codebasen in freier Wildbahn ansehen, werden Sie feststellen, dass die Leute manchmal Folgendes tun:
Dies liegt daran, dass einige C-Laufzeiten (ich erinnere mich sicher, dass dies unter PalmOS der Fall war) beim Freigeben eines
NULL
Zeigers abstürzen würden .Aber heutzutage glaube ich, dass es sicher ist anzunehmen, dass es sich um
free(NULL)
ein Nein handelt, wie es der Standard vorschreibt.quelle
free(ptr)
dassptr
Null keine Nebenwirkungen hat. Aber auf jeden Fall wird jeder Speicher, der mit verwendet wirdmalloc()
odercalloc()
danach freigegeben werden mussfree()
free(NULL)
indem er den ZeigerNULL
vor dem Aufruffree()
Alle standardkonformen Versionen der C-Bibliothek behandeln free (NULL) als No-Op.
Das heißt, zu einer Zeit gab es einige Versionen von Free, die auf Free (NULL) abstürzen würden, weshalb Sie möglicherweise einige defensive Programmiertechniken empfehlen:
quelle
sagt die Dokumentation.
quelle
Ich erinnere mich, dass ich an PalmOS gearbeitet habe, wo es
free(NULL)
abgestürzt ist.quelle
NULL
war einer der großen Unterschiede zwischen der Palm-Toolbox und der Standardbibliothek.Sie können einen NULL-Zeiger sicher löschen. In diesem Fall wird keine Operation ausgeführt. Mit anderen Worten, free () führt nichts an einem NULL-Zeiger aus.
quelle
Empfohlene Verwendung:
Sehen:
Wenn Sie den Zeiger auf setzen,
NULL
nachdemfree()
Siefree()
ihn erneut aufrufen können, wird keine Operation ausgeführt.quelle
free(NULL)
vollkommen legal ist auch in C wiedelete (void *)0
unddelete[] (void *)0
sind legal in C ++.Übrigens verursacht das zweimalige Freigeben von Speicher normalerweise einen Laufzeitfehler, sodass nichts beschädigt wird.
quelle
delete 0
ist in C ++ nicht legal.delete
erfordert explizit einen Ausdruck vom Zeigertyp. Es ist legal,delete
auf einen typisierten Nullzeigerwert anzuwenden , jedoch nicht auf0
(und nicht aufNULL
).void*
: P Welche Destruktoren sollten ausgeführt werden?void *
, solange es sich um einen Nullzeiger handelt.buf1=malloc(X); free(buf1);buf2=malloc(X);free(buf1);
- Wenn Sie Pech haben, hat buf2 genau die gleiche Adresse wie buf1 erhalten, und Sie haben buf1 versehentlich zweimal befreit irgendein (sofortiger) Fehler / Absturz / was auch immer. (aber Sie werden wahrscheinlich immer noch einen Absturz bekommen, wenn Sie das nächste Mal versuchen, buf2 zu verwenden - und dieses Szenario ist sehr unwahrscheinlich, wenn Sie auf ASLR laufen)free(ptr)
Speicher in C ist , wennptr
istNULL
jedoch, was die meisten Leute nicht wissen , das istNULL
notwendig auf 0 nicht gleich sein ich ein nettes Altschule Beispiel habe: Auf dem C64, auf Adresse 0, gibt es einen IO-Ports. Wenn Sie ein Programm in C geschrieben haben, das auf diesen Port zugreift, benötigen Sie einen Zeiger mit dem Wert 0. Die entsprechende C-Bibliothek müsste zwischen 0 undNULL
dann unterscheiden.Mit freundlichen Grüßen.
quelle
Keine Speicherbeschädigung, aber das Verhalten hängt von der Implementierung ab. Standardmäßig sollte es ein Gesetzbuch sein.
quelle
ptr zeigt auf einen Speicherort, sagen wir 0x100.
Wenn Sie (ptr) freigeben, erlauben Sie im Grunde, dass 0x100 vom Speichermanager für andere Aktivitäten oder Prozesse verwendet wird, und in einfachen Worten bedeutet dies, dass Ressourcen freigegeben werden.
Wenn Sie ptr = NULL ausführen, zeigt ptr auf eine neue Position (machen Sie sich keine Sorgen darüber, was NULL ist). Dadurch haben Sie den Überblick über die 0x100-Speicherdaten verloren. Dies ist ein Speicherverlust.
Es ist daher nicht ratsam, ptr = NULL für einen gültigen ptr zu verwenden.
Stattdessen können Sie eine sichere Überprüfung durchführen, indem Sie Folgendes verwenden:
if (ptr! = NULL) {free (ptr);}
Wenn Sie (ptr) freigeben, wobei ptr bereits auf NULL zeigt, wird keine Operation ausgeführt. Dies ist also sicher.
quelle