vector::back()-Referenz auch nach pop_back gültig?



  • Ist das hier erlaubt?

    struct pod { int data[256]; }; // Destruktor hat keinen Effekt
    vector<pod> v(10);
    pod& last = v.back();
    v.pop_back();
    // mach was mit "last", lasse "v" in Ruhe
    

    Die verschiedenen Dokumentationen sagen jeweils etwas anderes.

    http://www.cplusplus.com/reference/vector/vector/pop_back/ -- "reference[s] referring to the removed element are invalidated"
    http://en.cppreference.com/w/cpp/container/vector/pop_back -- "No iterators or references are invalidated."

    Aus meiner Sicht dürfte nichts dagegen sprechen, da der Vector den Speicher ja nicht freigeben darf.



  • Objekte sind mehr als nur Speicher.

    Ist das hier erlaubt?

    Ja, solange du nicht auf last zugreifst. 🙂

    Die verschiedenen Dokumentationen sagen jeweils etwas anderes.

    Und welche von beiden sieht vollstaendiger aus?



  • Guck mal in den Standard, da siehste ganz schnell wieso das nicht erlaubt ist.



  • Sone schrieb:

    Guck mal in den Standard, da siehste ganz schnell wieso das nicht erlaubt ist.

    Du mit deinem Standardgelaber. Als ob das eine Angelegenheit von 'ner Minute waere, wenn man ihn noch nie in der Hand gehabt hat. Schoen, dass du ihn gelesen hast, proll bitte woanders damit! Entweder du zitierst die Stelle oder laesst es!



  • Naja, so "ganz schnell" kann man jetzt nicht sagen. vector::pop_back wird im Standard nicht direkt behandelt, sondern über vector::erase definiert. Ich zitier mal aus C++03:

    ISO/IEC 14882:2003 23.1.1 (12) (Table 68) schrieb:

    expression   | return type | operational semantics | container
    -------------+-------------+-----------------------+--------------------
    (...)        | (...)       | (...)                 | (...)
    a.pop_back() | void        | a.erase(--a.end())    | vector, list, deque
    

    Und später

    ISO/IEC 14882:2003 23.2.4.3 (3) schrieb:

    iterator erase(iterator position);
    iterator erase(iterator first, iterator last);
    

    Effects: Invalidates all the iterators and references after the point of the erase.

    Dass "after the point of the erase" den Eingabeiterator mit einschließt, ist aus dem Kontext offensichtlich.

    Also nein, TEs Vorhaben ist nicht erlaubt, und es sollte mich nicht mal wundern, wenn die ein oder andere Implementation der Standardbibliothek da im Debug-Modus lustige Dinge draus macht. Den invalidierten Speicher mit magischen Zahlen überschreiben, damit der Debugger gleich merken kann, wenn man solchen Unfug treibt, zum Beispiel.


Log in to reply