352 Stimmen

Ist es sicher, einen NULL-Zeiger zu löschen?

Ist es sicher, einen NULL-Zeiger zu löschen?

Und ist das ein guter Kodierungsstil?

313voto

ruslik Punkte 14336

delete führt die Prüfung ohnehin durch, so dass die Prüfung auf Ihrer Seite zusätzlichen Aufwand bedeutet und unschön aussieht. A sehr gute Praxis ist das Setzen des Zeigers auf NULL nach delete (zur Vermeidung von Doppellöschungen und anderen ähnlichen Problemen mit dem Speicher).

Ich würde mich auch freuen, wenn delete wurde der Parameter standardmäßig auf NULL gesetzt, wie in

#define my_delete(x) {delete x; x = NULL;}

(Ich weiß, dass es R- und L-Werte gibt, aber wäre es nicht schön?)

89voto

Chubsdad Punkte 23861

Aus dem C++0x Standardentwurf.

$5.3.5/2 - "[...]In beiden Alternative kann der Wert des Operanden von delete ein Null-Zeiger sein value.[...'"

Natürlich würde niemand jemals einen Zeiger mit NULL-Wert löschen, aber es ist sicher zu tun. Idealerweise sollte man keinen Code haben, der das Löschen eines NULL-Zeigers durchführt. Aber es ist manchmal nützlich, wenn das Löschen von Zeigern (z.B. in einem Container) in einer Schleife geschieht. Da das Löschen eines NULL-Zeigers sicher ist, kann man die Löschlogik ohne explizite Prüfung auf einen zu löschenden NULL-Operanden schreiben.

Nebenbei bemerkt sagt der C-Standard $7.20.3.2 auch, dass 'free' auf einen NULL-Zeiger keine Wirkung hat.

T auf den ptr zeigt, wieder freigegeben wird, d.h. er wird für weitere Zuweisungen Zuweisung. Wenn ptr ein Null-Zeiger ist, findet keine Aktion statt.

56voto

Jonathan Leffler Punkte 694013

Ja, es ist sicher.

Es schadet nicht, einen Null-Zeiger zu löschen; es reduziert oft die Anzahl der Tests am Ende einer Funktion, wenn die nicht zugewiesenen Zeiger auf Null initialisiert und dann einfach gelöscht werden.


Da der vorangegangene Satz für Verwirrung gesorgt hat, ein Beispiel - das nicht ausnahmslos sicher ist - für das, was hier beschrieben wird:

void somefunc(void)
{
    SomeType *pst = 0;
    AnotherType *pat = 0;

    …
    pst = new SomeType;
    …
    if (…)
    {
        pat = new AnotherType[10];
        …
    }
    if (…)
    {
        …code using pat sometimes…
    }

    delete[] pat;
    delete pst;
}

Es gibt allerlei Schwachstellen, die man an dem Beispielcode ausmachen kann, aber das Konzept ist (so hoffe ich) klar. Die Zeigervariablen werden auf Null initialisiert, so dass die delete Operationen am Ende der Funktion brauchen nicht zu prüfen, ob sie im Quellcode ungleich Null sind; der Bibliothekscode führt diese Prüfung ohnehin durch.

22voto

Brian R. Bondy Punkte 325712

Das Löschen eines Null-Zeigers hat keine Auswirkungen. Es ist nicht unbedingt ein guter Kodierungsstil, weil es nicht benötigt wird, aber es ist auch nicht schlecht.

Wenn Sie auf der Suche nach guten Programmierpraktiken sind, sollten Sie die Verwendung von intelligenten Zeigern in Betracht ziehen, damit Sie nicht delete überhaupt nicht.

16voto

ashrasmun Punkte 170

Zur Ergänzung rusliks Antwort In C++14 können Sie diese Konstruktion verwenden:

delete std::exchange(heapObject, nullptr);

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X