Nach delete Zeiger benutzbar?


  • Mod

    camper schrieb:

    ist das nun irgendwie undefiniert, falls der if-Zweig ausgeführt wird? Ich denke nicht, allerdings bin ich nicht gänzlich sicher, dass der Wortlaut des Standards hier für eine definitive Aussage präzise genug ist. Das müsste geprüft werden.

    Die Antwort auf diese Frage ist aber die gleiche, ob es ok ist, einen Zeiger mit diesem Wert in einer map zu haben.


  • Mod

    SeppJ schrieb:

    camper schrieb:

    ist das nun irgendwie undefiniert, falls der if-Zweig ausgeführt wird? Ich denke nicht, allerdings bin ich nicht gänzlich sicher, dass der Wortlaut des Standards hier für eine definitive Aussage präzise genug ist. Das müsste geprüft werden.

    Die Antwort auf diese Frage ist aber die gleiche, ob es ok ist, einen Zeiger mit diesem Wert in einer map zu haben.

    Nicht unbedingt. Für den Fall, dass die Standardallokationsfunktion niemals direkt benachbarte Speicherbereiche anfordert, wird der if-Zeig niemals ausgeführt werden, die Frage stellt sich dann schon nicht mehr. Eine selbstdefinierte Allokationfunktion wiederum (die evtl. solche aufeinanderfolgenden Allokationen ermöglich) ist Teil des Programmes, und ein per delete freigegebener Speicherbereich wird vermutlich erst einmal in einen internen Pool wandeln, d.h. aus Sicht der Sprache bleibt der Speicher reserviert, mithin bleiben Zeiger gültig.
    Nicht umsonst handelt es sich im oben zitierten Code nur um eine Anmerkung, keine eigenständige Regel. Die Grundlage dafür findet sich im C-Standard:

    C99 6.2.4/2 schrieb:

    The lifetime of an object is the portion of program execution during which storage is guaranteed to be reserved for it. An object exists, has a constant address,25) and retains its last-stored value throughout its lifetime.26) If an object is referred to outside of its lifetime, the behavior is undefined. The value of a pointer becomes indeterminate when the object it points to reaches the end of its lifetime.



  • camper schrieb:

    SeppJ schrieb:

    int *a = new int, *b = new int;
    if (a - b == 1)
    {
     delete a;
     b = (b + 1) - 1;
    }
    

    Die Bedingung muss etwas anders geschrieben werden ( a == b + 1 ).

    Ich kann da jetzt keinen Unterschied erkennen. Warum ist es hier nötig die Bedingung so zu schreiben?



  • hourmin schrieb:

    camper schrieb:

    Die Bedingung muss etwas anders geschrieben werden ( a == b + 1 ).

    Ich kann da jetzt keinen Unterschied erkennen. Warum ist es hier nötig die Bedingung so zu schreiben?

    a-b ist nur erlaubt, wenn a und b in dasselbe Objekt hinein zeigen. Das ist hier nicht der Fall. b+1 ist ein Zeiger hinter das Ende von b, das ist erlaubt. Und zwei beliebige Zeiger, also auch a und b+1, dürfen auf Gleichheit geprüft werden.

    camper, richtig?


  • Mod

    Bashar schrieb:

    hourmin schrieb:

    camper schrieb:

    Die Bedingung muss etwas anders geschrieben werden ( a == b + 1 ).

    Ich kann da jetzt keinen Unterschied erkennen. Warum ist es hier nötig die Bedingung so zu schreiben?

    a-b ist nur erlaubt, wenn a und b in dasselbe Objekt hinein zeigen. Das ist hier nicht der Fall. b+1 ist ein Zeiger hinter das Ende von b, das ist erlaubt. Und zwei beliebige Zeiger, also auch a und b+1, dürfen auf Gleichheit geprüft werden.

    camper, richtig?

    Das ist die Idee. Ist Bedingung (in der korrigierten Form) wahr, kann man das Ganze natürlich auch so sehen, dass a und b zusammen einen zusammenhängenden Speicherbereich bilden, mithin wäre a-b in diesem Fall auch definiert.

    Ist die Bedingung hingegen nicht erfüllt, hätte die Subtraktion unmittelbar UB zur Folge. Mit diesem Wissen könnte ein Compiler auf die Idee kommen, die Bedingung (in ihrer ursprünglichen Form) einfach zu eliminieren und den if-Zweig immer auszuführen.

    Edit: Die andere Möglichkeit, die nicht zur UB zur Folge hätte, ware a+1 == b.


Anmelden zum Antworten