Überprüfung auf NULL, bevor Sie kostenlos anrufen

Lesezeit: 5 Minuten

Benutzer-Avatar
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?

  • 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

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:

  1. 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,

  2. 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.

Benutzer-Avatar
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.

Benutzer-Avatar
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

1369030cookie-checkÜberprüfung auf NULL, bevor Sie kostenlos anrufen

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

Privacy policy