Ist es sicher, einen Nullzeiger zu löschen?
Und ist es ein guter Codierungsstil?
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?)
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.
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.
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.
Um die Antwort von Ruslik zu ergänzen, können Sie in C++ 14 diese Konstruktion verwenden:
delete std::exchange(heapObject, nullptr);
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.
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.