web-dev-qa-db-ger.com

Ist es sicher, einen Nullzeiger zu löschen?

Ist es sicher, einen Nullzeiger zu löschen?

Und ist es ein guter Codierungsstil?

276
qiuxiafei

delete führt die Prüfung trotzdem durch. Wenn Sie es also auf Ihrer Seite prüfen, wird der Aufwand erhöht und es sieht hässlicher aus. Eine sehr gute Vorgehensweise besteht darin, den Zeiger nach delete auf NULL zu setzen (dies vermeidet das doppelte Löschen und ähnliche Probleme mit der Speicherbeschädigung).

Ich würde auch lieben, wenn delete standardmäßig den Parameter auf NULL wie in setzen würde

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

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

241
ruslik

Aus dem C++ 0x-Standardentwurf.

$ 5.3.5/2 - [...] In beiden Alternativen kann der Wert des Operanden von delete ein Nullzeigerwert sein. [... '"

Natürlich würde niemand jemals einen Zeiger mit NULL-Wert 'löschen', aber das ist sicher. Idealerweise sollte man keinen Code haben, der einen NULL-Zeiger löscht. Es ist jedoch manchmal nützlich, wenn das Löschen von Zeigern (z. B. in einem Container) in einer Schleife erfolgt. Da das Löschen eines NULL-Zeigerwerts sicher ist, kann man die Löschlogik wirklich schreiben, ohne explizit nach dem zu löschenden NULL-Operanden zu suchen.

Abgesehen davon sagt C Standard $ 7.20.3.2 auch, dass 'free' auf einem NULL-Zeiger keine Aktion ausführt.

Die Funktion free bewirkt, dass der Speicherplatz, auf den ptr zeigt, freigegeben wird, dh für die weitere Zuordnung verfügbar gemacht wird. Wenn ptr ein Nullzeiger ist, wird keine Aktion ausgeführt.

73
Chubsdad

Ja, es ist sicher.

Das Löschen eines Nullzeigers schadet nicht. Oft wird die Anzahl der Tests am Ende einer Funktion reduziert, wenn die nicht zugewiesenen Zeiger auf Null initialisiert und dann einfach gelöscht werden.


Da der vorige Satz Verwirrung gestiftet hat, ist ein Beispiel, das nicht ausnahmesicher ist, für das Beschriebene:

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 alle Arten von Nissen, die mit dem Beispielcode ausgewählt werden können, aber das Konzept ist (ich hoffe) klar. Die Zeigervariablen werden mit Null initialisiert, damit die delete -Operationen am Ende der Funktion nicht testen müssen, ob sie im Quellcode nicht null sind. Der Bibliothekscode führt diese Prüfung trotzdem durch.

44

Das Löschen eines Nullzeigers hat keine Auswirkung. Es ist nicht unbedingt ein guter Codierungsstil, weil er nicht benötigt wird, aber es ist auch nicht schlecht.

Wenn Sie nach einer guten Codierungspraxis suchen, ziehen Sie stattdessen die Verwendung von intelligenten Zeigern in Betracht, sodass Sie delete überhaupt nicht benötigen.

20
Brian R. Bondy

Um die Antwort von Ruslik zu ergänzen, können Sie in C++ 14 diese Konstruktion verwenden:

delete std::exchange(heapObject, nullptr);
5
ashrasmun

Dies ist nur dann sicher, wenn Sie den Löschoperator überladen haben. Wenn Sie den Löschoperator überladen haben und keine Nullbedingung verarbeiten, ist dies überhaupt nicht sicher.

3
user4016479

Ich habe erfahren, dass es nicht sicher ist (VS2010), [] NULL (d. H. Array-Syntax) zu löschen. Ich bin nicht sicher, ob dies dem C++ - Standard entspricht.

Es ist sicher, NULL (skalare Syntax) zu löschen.

0
pheest