Ist der end Iterator konstant?



  • Mahlzeit

    eine Frage zu Map Iteratoren. Wenn ich mir einen Iterator auf das Ende hinter der Map merke:

    Iterator itEnd = myMap.end();
    // Map editieren (einfuegen, loeschen etc.)
    // ...
    Iterator itEnd2 = myMap.end();
    // Ist hier sichergestellt, dass itEnd2 == itEnd ?
    

    Und dann bearbeite ich die Map (insert etc.) und hole mir dann erneut einen Iterator per end(). Ist dann garantiert, dass die 2 End Zeiger die gleichen sind? Oder liefert das end() dann einen neuen Iterator?


  • Mod

    Ich finde es gerade nicht, aber du kannst davon ausgehen, dass das funktioniert. Wenn im Standard nicht ausdrücklich steht, dass Iteratoren durch eine Aktion ungültig werden, dann werden sie das auch nicht.

    Intern ist der end()-Iterator übrigens (zumindest bei den mir bekannten Implementierungen) ein Zeiger auf die internen Datenstrukturen der map selbst. Und deren Adressen ändern sich nicht, wenn man etwas einfügt.



  • Also bei einer map und auch list, werden beim löschen nur Iteratoren auf die zu löschenden Elemente ungültig, der Rest nicht. Beim Einfügen bleiben sie so weit ich weiß auch gültig.

    Bei einem Vektor, sieht das ganz anders aus, dort können je nachdem bei einem Einfügen oder Löschen alle Iteratoren ungültig werden.

    Lg freeG



  • Wo findet man denn eine kompakte Auflistung, welche Iteratoren bei welchen
    Aktionen ungültig werden?



  • Auflistung schrieb:

    Wo findet man denn eine kompakte Auflistung, welche Iteratoren bei welchen
    Aktionen ungültig werden?

    Definiere Kompakt. Es sind bloß vier Sätze im Standard:
    23.2.1.3: deque modifiers (-> insert und erase machen alle iteratoren ungültig.)
    23.2.2.3: list modifiers (-> insert invalidiert nichts, erase nur Iteratoren auf das gelöshte Element)
    23.2.4.2: vector modifiers (insert invalidiert genau dann alle Iteratoren, wenn die neue Größe die alta kapazität übersteigt, weil der Speicher neu alloziiert werden muss. Erase invalidiert alle Iteratoren hinter dem gelöschen Element.)
    23.1.2 Associative Containers (d.h. [multi]map, [multi|bit]set) (insert invalidiert nichts, erase nur Iteratoren auf das gelöschte Element)

    Das wars.



  • Zusatz bei vector: insert invalidiert, wenn die Kapazität ausreicht, alle Iteratoren hinter dem eingefügten Element.



  • pumuckl schrieb:

    23.2.4.2: vector modifiers (insert invalidiert genau dann alle Iteratoren, wenn die neue Größe die alta kapazität übersteigt, weil der Speicher neu alloziiert werden muss. Erase invalidiert alle Iteratoren hinter dem gelöschen Element.)

    Gilt das auch fuer Zeiger?

    Beispiel:

    vector<Foo> v;
    v.push_back(...);
    v.push_back(...);
    v.push_back(...);
    ...
    Foo* f = &v[2];
    // A
    v.push_back(...);
    v.push_back(...);
    v.push_back(...);
    
    Zeigt jetzt f auf jeden Fall noch auf das selbe Element wie an der Stelle A?
    


  • Ja, das gilt auch für Zeiger auf die Elemente. Es kann also sein, dass f nicht mehr auf einen gültigen Speicherbereich zeigt.


  • Administrator

    Auflistung schrieb:

    Wo findet man denn eine kompakte Auflistung, welche Iteratoren bei welchen
    Aktionen ungültig werden?

    Sowas? http://magazin.c-plusplus.net/artikel/Aufbau%20der%20STL%20-%20Teil%201%3A%20Container (ganz unten)

    Grüssli


Log in to reply