, die sicherlich nicht definiertes Verhalten ist (durch den gesunden Menschenverstand, und dem Wortlaut der Norm).
Soweit der Standard geht, 3.8/5 ist ziemlich konkret zu wissen, was erlaubt ist und was nicht ist:
[...] nach der Lebensdauer eines Objekts beendet und vor der Speicher, den das Objekt belegt hat, wiederverwendet oder freigegeben wird, kann jeder Zeiger verwendet werden, der sich auf den Speicherort bezieht, an dem sich das Objekt befindet oder befand [...] und den Zeiger als ob der Zeiger verwenden waren vom Typ void *, ist wohldefiniert.
Indirection [...] ist wie unten beschrieben erlaubt.Das Programm Verhalten, wenn nicht definiert hat:
- ...
- [...] verwendet als Operand static_cast
, es sei denn, die Umstellung auf cv auf Zeiger ist void
oder void
zu cv auf Zeiger und anschließend Zeiger entweder cv cv char
oder unsigned char
- [...] als Operand am Ende des Bereichs verwendet dynamic_cast
die Objektspeicher pro 3.7.3/1 (in der Praxis endet Dies ist höchstwahrscheinlich nicht wahr, der Stack-Frame wird wahrscheinlich am Ende der Funktion zurückgesetzt n, aber formell das ist was passiert). Daher tritt die Dereferenzierung nicht nach Ablauf der Lebenszeit auf sondern vor die Freigabe des Speichers. Es passiert nach Freigabe des Speichers.
Die speziellen Bedingungen, unter denen Sie den Zeiger trotzdem dereferenzieren können, gelten daher nicht (dasselbe gilt für ähnliche Absätze mit derselben Vorbedingung wie 3.8/6).
der weiteren Annahme, daß der vorigen Absatz nicht wahr war, ist es nur zulässig zu dereferenzieren den Zeiger als cv void*
oder an cv char
(mit oder ohne Vorzeichen) vor dereferenzieren zu werfen. Mit anderen Worten, Sie sind nicht erlaubt, um die spitz zu int
zu betrachten, als ob es ein int
wäre. Wie in 3.8/5 angegeben, ist die int*
wirklich nur eine void*
nach der Lebensdauer des Objekts. Das bedeutet, dass die Dereferenzierung als int*
einer Umwandlung gleichkommt (nicht explizit, aber immer noch).
Man würde wirklich wünschen, dass dieser Versuch einen Fehler erzeugt, aber ich denke, das ist ein wirklich schwieriger für den Compiler zu erkennen. Der Zeiger selbst ist gut und lebendig und wurde sicher abgeleitet, indem die Adresse eines gültigen Objekts genommen wurde, was wahrscheinlich fast unmöglich zu diagnostizieren ist.
Ich glaube, 'p' wird immer noch auf den Speicherort zeigen, wo' n' war, aber Sie haben keine Möglichkeit zu wissen, was da sein wird. – mstbaum
@mstbaum und wie ist das mit der Frage verbunden? – Slava
@remyabel (Mein vorher gelöschter Kommentar, der gefragt wird, ob "die Ergebnisse nicht vorhersagen können" impliziert UB.) Vielleicht bin ich nicht klar, was undefiniertes Verhalten ist. Meine Argumentation ist wahrscheinlich ähnlich wie bei Mstbaum, da wir nicht wissen, was sich an diesem Ort im Speicher befindet, sodass wir die Ergebnisse nicht vorhersagen können. Reicht das nicht aus? Muss ich im Standard nachsehen, um sicher zu gehen? – eigenchris