Viele Aufrufe zum Freigeben von Zeigern in C-Code:
if (p)
free(p);
Aber wieso? Ich dachte, C-Standard sagen die free
Die Funktion macht bei einem NULL-Zeiger nichts. Warum also noch eine explizite Prüfung?
Zaharpopov
Viele Aufrufe zum Freigeben von Zeigern in C-Code:
if (p)
free(p);
Aber wieso? Ich dachte, C-Standard sagen die free
Die Funktion macht bei einem NULL-Zeiger nichts. Warum also noch eine explizite Prüfung?
Das Konstrukt:
free(NULL);
war in C immer in Ordnung, zurück zum ursprünglichen UNIX-Compiler, der von Dennis Ritchie geschrieben wurde. Vor der Standardisierung haben einige schlechte Compiler es vielleicht nicht richtig eingesetzt, aber heutzutage kann sich jeder Compiler, der sich nicht als Compiler für die C-Sprache bezeichnen darf, legitimerweise nicht nennen. Die Verwendung führt in der Regel zu klarerem, besser wartbarem Code.
Soweit ich weiß, war das No-Op auf NULL nicht immer da.
In den schlechten alten Tagen von C (damals um 1986 auf einem cc-Compiler vor dem ANSI-Standard) würde free(NULL) den Kern ausgeben. Daher haben die meisten Entwickler auf NULL/0 getestet, bevor sie kostenlos angerufen haben.
Die Welt hat einen langen Weg zurückgelegt, und es scheint, dass wir den Test nicht mehr durchführen müssen. Aber alte Gewohnheiten sterben schwer;)
http://discuss.joelonsoftware.com/default.asp?design.4.194233.15
+1 Daran erinnere ich mich, aber ich konnte den Verweis darauf nicht finden.
– Matt Davis
16. Dezember 2009 um 4:45 Uhr
Soweit ich weiß, existierte dieser Fehler in einigen Compilern auch nach der Standardisierung.
– Michael Burr
16. Dezember 2009 um 7:45 Uhr
Es war immer da, sogar in der ursprünglichen UNIX-Implementierung. Dies wird in PJ Plaugers Artikel über den Standardisierungsprozess erwähnt – kann jedoch derzeit keine genaue Referenz finden.
– anon
16. Dezember 2009 um 11:45 Uhr
Der Tag, an dem Joel als technische Autorität zitiert wird, ist ein trauriger Tag für die Menschheit.
– anon
16. Dezember 2009 um 11:48 Uhr
Neil: Das ist ein Zitat aus dem Forum auf der Joel-Website, das eigentliche Zitat nicht von ihm, sondern von jemandem namens Guidii. Ich denke also, dass die Menschheit heute gerettet wurde
– saharpopow
16. Dezember 2009 um 13:10 Uhr
Ich neige dazu zu schreiben “if (p) free(p)
„viel, auch wenn ich weiß, dass es nicht nötig ist.
Ich mache mir teilweise selbst Vorwürfe, weil ich früher C gelernt habe free(NULL)
würde segfault und ich fühle mich immer noch unwohl, es nicht zu tun.
Aber ich beschuldige auch den C-Standard, nicht konsistent zu sein. Wäre zum Beispiel fclose(NULL) wohldefiniert, hätte ich keine Probleme beim Schreiben:
free(p);
fclose(f);
Was beim Aufräumen sehr oft vorkommt. Leider kommt es mir seltsam vor zu schreiben
free(p);
if (f) fclose(f);
und ich am Ende mit
if (p) free(p);
if (f) fclose(f);
Ich weiß, es ist kein rationaler Grund, aber das ist mein Fall 🙂
Ja, diese Antwort weist auf den Mangel an Konsistenz in C hin, und es ist tatsächlich ein Overhead für den Programmierer, die richtigen Praktiken zu verfolgen.
– Aashima
9. Mai 2021 um 14:15 Uhr
Compiler sind selbst beim Inlining nicht intelligent genug, um zu wissen, dass die Funktion sofort zurückgegeben wird. Das Schieben von Parametern usw. auf den Stapel und das Einrichten des Aufrufs ist offensichtlich teurer als das Testen eines Zeigers. Ich denke, es ist immer eine gute Praxis, die Ausführung von irgendetwas zu vermeiden, selbst wenn es sich um eine No-Op handelt. Das Testen auf null ist eine gute Praxis. Eine noch bessere Vorgehensweise besteht darin, sicherzustellen, dass Ihr Code diesen Zustand nicht erreicht, und somit die Notwendigkeit für den Test insgesamt zu eliminieren.
Es gibt zwei verschiedene Gründe, warum eine Zeigervariable NULL sein kann:
weil die Variable für das verwendet wird, was in der Typentheorie als an bezeichnet wird Optionstypund enthält entweder einen Zeiger auf ein Objekt oder NULL zur Darstellung nichts,
weil es auf ein Array zeigt und daher NULL sein kann, wenn das Array eine Länge von Null hat (wie malloc(0)
darf NULL zurückgeben, implementierungsdefiniert).
Obwohl dies nur eine logische Unterscheidung ist (in C gibt es keine Optionstypen auch nicht besonders Zeiger auf Arrays und wir verwenden für alles einfach Zeiger), sollte immer deutlich gemacht werden, wie eine Variable verwendet wird.
Das verlangt die C-Norm free(NULL)
Nichtstun ist das notwendige Gegenstück dazu, dass ein erfolgreicher Aufruf dazu führt malloc(0)
kann zurückkehren NULL
. Es ist nicht als allgemeine Annehmlichkeit gedacht, weshalb zum Beispiel fclose()
tut erfordern ein Nicht-NULL-Argument. Missbrauch der Anruferlaubnis free(NULL)
Durch das Übergeben einer NULL, die kein Array der Länge Null darstellt, fühlt es sich hackisch und falsch an.
Pavel Radzivilovsky
Wenn Sie sich darauf verlassen, dass free(0) OKAY ist und es normal ist, dass Ihr Zeiger an dieser Stelle null ist, sagen Sie dies bitte im Kommentar // may be NULL
Dies kann nur ein selbsterklärender Code sein, der sagt ja ich weiß, ich benutze auch p als Flag.
CodingLab
Es kann eine benutzerdefinierte Implementierung von free() in der mobilen Umgebung geben. In diesem Fall kann free(0) ein Problem verursachen. (ja, schlechte Umsetzung)
Eine neue C-Implementierung, wenn sie heute gestartet wird, hat keine Entschuldigung dafür, einen solchen Fehler zu produzieren. Die C-Normen sind in diesem Punkt eindeutig.
– Vog
23. Dezember 2010 um 14:02 Uhr
@vog: Freistehende Implementierungen müssen nicht bereitgestellt werden malloc()
und free()
überhaupt, erlaubt aber normalerweise dem Benutzercode, solche Funktionen nach eigenem Ermessen zu definieren. Das Einschließen einer expliziten Nullprüfung sorgt dafür, dass der Code auch in Anwesenheit von funktioniert #define free(x) customReleaseThatDoesntLikeNull(x)
.
– Superkatze
17. April 2018 um 17:10 Uhr
Weil die Leute den C-Standard nicht kennen?
– Chris Lutz
16. Dezember 2009 um 4:41 Uhr
Duplizieren, ish von stackoverflow.com/questions/615355/…
– McPherrinM
16. Dezember 2009 um 4:43 Uhr
WaffleMatt: Das ist ungefähr C++ (und kein C++-Tag 🙁 ) – meins ist C, also ist es ein bisschen anders. C++ ist neuer, also haben “alte Gewohnheiten” dort vielleicht weniger Zugkraft
– saharpopow
16. Dezember 2009 um 4:46 Uhr
Das ist, wo das “ish” ist. Also sollte ich sagen, dass dieser Artikel auch von Interesse sein kann, auch wenn es kein Duplikat ist.
– McPherrinM
16. Dezember 2009 um 4:50 Uhr
@zaharpopov: Ich habe c++ zu 615355 hinzugefügt.
– abschalten
16. Dezember 2009 um 11:48 Uhr