Verhalten definiert?



  • Hallo

    Ist das Verhalten dieses Quellcodes definiert?

    int *foo = new int[13];
    delete &foo[12];
    

    MfG, EOutOfResources



  • Nein. Wie kommst du überhaupt darauf, und als was sollte das ggf. definiert sein?



  • Nein, natürlich nicht. Was sollte deiner Erwartung nach passieren?



  • Mein Kollege hat mit mir gewettet, dass dieser Code das Array um ein Element verkleinert.

    Danke und mfG, EOutOfResources.



  • EOutOfResources schrieb:

    Ist das Verhalten dieses Quellcodes definiert?

    Nö.



  • Es ist allerdings möglich, dass er die Prozesstabelle des Betriebssystems um ein Element verkleinert.

    Die relevante Stelle im Standard ist übrigens 5.3.5 (2):

    ISO/IEC 14882:2003 5.3.5 (2) schrieb:

    In the first alternative (delete object), the value of the operand of delete shall be a pointer to a non-array object or a pointer to a sub-object (1.8) representing a base class of such an object (clause 10). If not, the behavior is undefined.



  • Da steht doch eindeutig, dass der Pointer nicht auf einen Array zeigen darf, also geht es nicht.



  • Ah, Moment, da hab ich mich vertan - mental einen nicht vorhandenen Halbsatz eingefügt. Das Loch geht noch ein bisschen tiefer.

    Also,

    delete &foo[12];
    

    wird operator delete mit &foo[12] aufrufen (vgl. 5.3.5 (7-8)). Wenn dieser so überladen wurde, dass die Operation unterstützt wird, ist das Verhalten damit definiert. Wird allerdings der Standard-operator delete (18.4.1.1 (9-14)) benutzt, ist das Verhalten deshalb undefiniert, weil dieser nur Zeiger verarbeiten muss, die früher vom Standard-operator new zurückgegeben wurden. Das ist bei &foo[12] nicht der Fall.

    Wenn ihr also eine eigene dynamische Speicherverwaltung geschrieben habt, die so etwas kann, ist das Verhalten definiert. Ist das nicht der Fall (und ich nehme an, dass es das nicht ist), ist es undefiniert.


Anmelden zum Antworten