Warum funktionieren Pointer nach dem Löschen immer noch?
-
Habe mich schon immer gefragt, warum unten stehender Code funktioniert und richtig läuft.
Die einzige Antwort, die ich mal gefunden hatte war, dass der Speicher praktisch einfach nur freigegeben wird und jetzt theoretisch von jedem anderen Programm überschrieben werden könnte.int* pointer = new int; delete pointer; *pointer = 123; cout << *pointer << endl;Würde mich über eine Erklärung freuen.
-
Das Verhalten ist undefiniert. Man weiss also nicht, was passiert. Es kann sein, dass das Programm problemlos weiterläuft. Es kann aber auch crashen.
-
Das was du da fabriziert hast, nennt sich undefiniertes Verhalten. Mit dem delete gibst du nur den Speicher frei, den new angefordert hat, aber der Zeiger zeigt trotzdem noch auf die selbe Adresse. Was der Heap-Manager mit diesem Speicher macht, ist seine Angelegenheit (wenn du Pech hast, fliegt dir der Code um die Ohren, weil der Speicher beim nächsten new-Aufruf belegt worden ist).
-
Das Verhalten ist sehr wohl definiert. Bei dir aufm Rechner wirds immer wunderbar laufen. Beim Kunden wirds dir peinlichst um die Ohren fliegen.

-
Dobi schrieb:
Das Verhalten ist sehr wohl definiert. Bei dir aufm Rechner wirds immer wunderbar laufen. Beim Kunden wirds dir peinlichst um die Ohren fliegen.

Wie ist es denn definiert?
-
icarus2 schrieb:
Dobi schrieb:
Das Verhalten ist sehr wohl definiert. Bei dir aufm Rechner wirds immer wunderbar laufen. Beim Kunden wirds dir peinlichst um die Ohren fliegen.

Wie ist es denn definiert?
Ich glaube du hast den Witz nicht verstanden. Das hier tatsächlich wohl definierte verhalten ist, dass mit Sicherheit Murphys Gesetz zuschlägt, wenn man undefiniertes Verhalten programmiert.
-
SeppJ schrieb:
icarus2 schrieb:
Dobi schrieb:
Das Verhalten ist sehr wohl definiert. Bei dir aufm Rechner wirds immer wunderbar laufen. Beim Kunden wirds dir peinlichst um die Ohren fliegen.

Wie ist es denn definiert?
Ich glaube du hast den Witz nicht verstanden. Das hier tatsächlich wohl definierte verhalten ist, dass mit Sicherheit Murphys Gesetz zuschlägt, wenn man undefiniertes Verhalten programmiert.
Achsooo
*Blush*
-
delete pointer;gibt nur den zugewiesenen Speicherbereich wieder frei, löscht aber nicht die Zeigervariabel, d.h. pointer zeigt immer noch auf die Adresse, auch wenn da jetzt nach der Freigabe sonst was drin stehen kann (undefiniert).
Deswegen ist es gut einen Zeiger nach der delete Funktion auf 0 zu setzen.delete pointer; pointer = 0; if (pointer == 0) { ... }Gruß, x3meblue
-
x3meblue schrieb:
Deswegen ist es gut einen Zeiger nach der delete Funktion auf 0 zu setzen.
I disagree

Wenn du so eine Logik verwendest, ist dein Design (meistens) in den Fritten.
-
Disagree schrieb:
I disagree

Wenn du so eine Logik verwendest, ist dein Design (meistens) in den Fritten.Sehe ich auch so. Lieber dafür sorgen, dass der Zeiger solange wie möglich gültig ist und nachher kein Zugriff mehr darauf erfolgt.
Auch
deletezu verwenden ist ein Hinweis darauf, dass man vielleicht besser RAII einsetzen würde.
-
x3meblue schrieb:
Deswegen ist es gut einen Zeiger nach der delete Funktion auf 0 zu setzen.
- delete Funktion gibts nicht.
- Es ist nicht unbedingt gut, einen Zeiger nach der delete-Funktion auf 0 zu setzen. Ausnahmen sind Zeiger, die Bestandteile von Objekten sind, und wo es in Ordnung ist, wenn die 0 sind. An allen anderen Stellen sollte der Scope so oder so kurz nach dem delete verlassen werden, der Pointer verschwinden und muss deshalb nicht "nullifiziert" werden.
-
soya_crack schrieb:
[...] warum unten stehender Code funktioniert und richtig läuft.
Die offensichtliche Erklärung fehlt imho: Weil Deine Definition von "funktioniert" falsch ist. Im gegebenen Beispiel bekommst Du nur _zufällig_ das Ergebnis, was Du erwartest, obwohl das Programm inkorrekt ist.
Das wäre etwas vergleichbar damit ein kaputtes Auto einen Berg runterrollen zu lassen und dann zu argumentieren, das Auto sei ja nicht kaputt weil es fährt.
-
Ja, da habe ich mich vielleicht etwas falsch ausgedrückt. Ich meinte natürlich "läuft" und nicht gleich abschmiert.
Danke für die prompten Antworten, war ja dann so wie ich es mir vorgestellt habe.
-
Das wäre etwas vergleichbar damit ein kaputtes Auto einen Berg runterrollen zu lassen und dann zu argumentieren, das Auto sei ja nicht kaputt weil es fährt.

-
@Disagree: Wäre gut, wenn du auch erklären könntest warum, dann hätten alle was davon, so ist dein Beitrag sowohl überflüssig als auch nutzlos.
Gruß, x3meblue
-
x3meblue schrieb:
@Disagree: Wäre gut, wenn du auch erklären könntest warum, dann hätten alle was davon, so ist dein Beitrag sowohl überflüssig als auch nutzlos.
Gruß, x3meblue
Er hat doch erklärt, dass es auf Designfehler hindeutet. Nexus hat bessere Alternativen genannt. Wenn bei deinem Programm überhaupt die Chance besteht, dass ein ungültiger Pointer gelöscht wird, dann ist schon was falsch. Und mit dem Nullsetzen verschleppst du den Fehler auch noch, wodurch er wesentlich schwerer zu finden ist. Überhaupt sollte ein ungültiger Pointer kurz vorm Ende seiner Lebenszeit stehen (siehe auch wieder Nexus).
Nullsetzen solltest du nur, wenn dies einen besonderen Wert des Pointers bedeutet der an anderer Stelle auch geprüft wird (und zwar nicht vom delete!) und der Pointer danach überhaupt noch weiterlebt, z.B. wird das in komplexen Datenstrukturen wie Binärbäumen oft gemacht.
-
sagt mal:
wieso ist es eigentlich sinnvoll (bzw nicht vom std vorgeschrieben) dass delete den zeiger nicht automatisch gleich mit auf 0 setzt?
-
Erstens kostet es ein wenig Performance und man bezahlt bekanntlich für nichts, was man nicht braucht.
Zweitens bekommst du kein konsistentes Verhalten hin:
int* x = new int; int* y = x; delete y; // x == 0?
-
Skym0sh0 schrieb:
wieso ist es eigentlich sinnvoll (bzw nicht vom std vorgeschrieben) dass delete den zeiger nicht automatisch gleich mit auf 0 setzt?
Wurde doch schon gesagt dass das 0 setzen des Zeigers gefährlich sein kann.
Warum sollte man das also wollen?Nie nie nie den Zeiger 0 setzen. Das fürht zu den blödsten Problemen...
-
Nun, an anderen Stellen hört man es umgekehrt, nämlich, das auf 0 setzen gängige Praxis und es eben nicht gefährlich ist. Scheint wohl so ein Thema zu sein, wo es geteilte Meinungen gibt und jeder selbst entscheiden muss. Aber gut, das war ja auch nicht das eigentlich Thema des Threads.
Grüßla, x3meblue