Löschen von dynamisch zugewiesenen Variablen, die den Zeiger auf 0 setzen [duplizieren]

7

Ich kann das Ende dieses Codes ( array = 0; ) nicht verstehen:

%Vor%

Am Ende wird ein dynamisch alloziertes Array gelöscht (in das OS zurückgeschrieben) und dann den Wert 0 erhalten.

Warum ist das so? Nachdem Array an das Betriebssystem zurückgegeben wurde, muss ihm kein Wert von 0 zugewiesen werden, richtig?

Code von: Ссылка

    
bob 28.08.2017, 08:09
quelle

4 Antworten

15
  

Nachdem das Array an das Betriebssystem zurückgegeben wurde, muss ihm kein Wert von 0 zugewiesen werden, richtig?

Sie haben recht, es wird nicht benötigt, da der Speicher vom Operator% co_de freigegeben (freigegeben) wird % Aber denken Sie an einen Fall, in dem Sie den Zeiger an einer anderen Stelle in Ihrem Code verwenden können (Funktionen, Schleifen usw.), nachdem Sie delete darauf verwendet haben.

Die delete[] Variable enthält immer noch die Adresse der alten Zuweisung, nachdem die array Anweisung (dangling pointer) . Wenn Sie auf diese Adresse zugreifen würden, würden Sie undefined bahaviour (UB) erhalten, weil die Erinnerung nicht mehr Ihnen gehört, In den meisten Fällen stürzt Ihr Programm ab.

Um zu vermeiden, dass Sie einen Nullzeiger überprüfen, wie:

%Vor%

überprüft den Zeiger auf die Adresse 0, die eine ungültige Adresse darstellt.

Um diese Prüfung zu ermöglichen, setzen Sie den Zeiger auf delete[] oder nullptr , wenn C ++ 11 nicht verfügbar ist. Das Schlüsselwort NULL führt die Typsicherheit ein, da es sich wie ein Zeigertyp verhält und gegenüber dem C-ähnlichen nullptr vorzuziehen ist. In pre C ++ 11 NULL ist als ganze Zahl 0 definiert, da C ++ 11 ein Alias ​​für NULL ist.
Um Ihr eigenes nullptr zu definieren, um es für den C ++ 11 Compiler zu verwenden, klicken Sie hier: Wie definieren wir unser eigenes nullptr in C ++? 98?

Eine interessante Tatsache über nullptr oder delete ist, dass es sicher ist, sie in delete[] zu verwenden. Es steht unter Punkt 2 auf cppreference.com oder unter SO Antwort .

  

Operator löschen, Operator löschen []

     

2)   [...] Das Verhalten der Standardbibliotheksimplementierung dieser Funktion ist nicht definiert, es sei denn, nullptr ist ein Nullzeiger oder ein Zeiger, der zuvor von der Standardbibliotheksimplementierung von ptr oder operator operator new[](size_t) erhalten wurde.

    
Andre Kampling 28.08.2017, 08:17
quelle
8

Wir setzen Zeiger auf NULL (0), um hängende Zeiger zu vermeiden (der Zeiger zeigt immer noch auf denselben Speicher, der nicht mehr Ihr ist). Im Falle von lokalen Variablen ist dies nicht sinnvoll, wenn die Funktion nach dem Löschen nicht fortgesetzt wird (der Zeiger wird also nicht wiederverwendet). Im Fall von globalen / Mitglieder poitners seine gute Praxis, um Bugs zu vermeiden.

Der Zugriff auf bereits gelöschte Zeiger kann zum Überschreiben / Lesen von zufälligem Speicher führen (es könnte gefährlicher sein als Absturz) und undefiniertes Verhalten , während der Zugriff auf NULL Zeiger sofort abstürzt.

Seit getaggt sind sollte nullptr verwenden, weil es als Zeigertyp definiert ist, während NULL mehr int type ist und Typsicherheit verbessert + mehrdeutige Situationen löst.

Im Falle des doppelten Löschens des Zeigers ist es sicher, delete auf nullptr zu verwenden, und nichts passiert, aber wenn Sie bereits gelöschten Nicht-Null-Zeiger löschen, wird dies undefined Verhalten und das wahrscheinlichste Programm wird abstürzen.

In sollten Sie darauf verzichten, reine Zeiger zu verwenden Es gibt STL-Container (die ihre Ressourcen selbst freigeben ( RAII <) / a>)) für diese Verwendung oder intelligente Zeiger .

%Vor%     
Filip Kočica 28.08.2017 08:18
quelle
3

Dies geschieht, damit der Zeiger auf NULL gesetzt wird (egal ob in C ++, wir bevorzugen nullptr , da NULL und 0 verschiedene Dinge sind).

Diese Taktik eliminiert die Möglichkeit eines dangling pointers , weil das Array möglicherweise gelöscht wurde, aber das bedeutet nicht, dass es auf NULL gesetzt ist.

Wenn wir das nicht tun, riskieren wir zu überprüfen, ob der Zeiger NULL oder nicht ist (letzteres in unserem Code), wir werden sehen, dass es nicht NULL ist, glaube fälschlicherweise, dass der Zeiger in Ordnung ist auf zugegriffen werden und Undefined Behavior verursachen.

    
gsamaras 28.08.2017 08:13
quelle
1

Sie weisen einen Wert zu, der allgemein als "ungültige Adresse" bezeichnet wird, d. h. NULL , 0 oder den Zeigertyp nullptr , da Sie ansonsten nicht wissen können, ob der Zeiger auf eine ungültige Adresse zeigt. Mit anderen Worten, wenn Sie delete[] Ihr Array Ihren Zeiger "weiß nicht", dass es auf eine nicht mehr verwendbare Speicheradresse verweist.

    
Ziezi 28.08.2017 08:53
quelle