[gelöst] komisches verhalten von std::vector<std::string>, g++ 4.4.1



  • ja, der zeigt aber auf ein element aus der liste ans, also auf einen double-wert. sorgen bereiten mir die elemente der string-liste ansnames.


  • Mod

    Dein Problem wurde dir ja schon erklärt. Außerdem will ich noch hinzufügen, dass Bezeichner mit zwei Unterstrichen oder einem Unterstrich am Anfang für Compilerimplementierungen reserviert sind und nicht verwendet werden sollten.



  • @SeppJ: Danke, werde ich in Zukunft berücksichtigen.



  • gahre schrieb:

    ja, der zeigt aber auf ein element aus der liste ans, also auf einen double-wert. sorgen bereiten mir die elemente der string-liste ansnames.

    Nein tut er nicht, an dieser Stelle kann sich jetzt was anderes befinden. Da sich ansnames von der Groesse geandert hat, koennen sich dort auch Teile von ansnames befinden. Wenn man mit Containern arbeitet, sollte man auch in erster Linie Iteratoren bevorzugen. Es sind einfach die C++-Sprachmittel. Abschliessend: Es besteht ein unterschied zwischen einer Liste (std::list) und einem Array (std::vector).


  • Mod

    gahre schrieb:

    ja, der zeigt aber auf ein element aus der liste ans

    Eben nicht. Die Liste liegt nach dem Einfügen der Elemente ganz woanders, dein Iterator (oder Zeiger, wenn du es so nennen willst) zeigt aber immer noch auf die alte Stelle. Als ich dein Programm ausgeführt habe, habe ich beispielsweise einen Fehler bekommen, dass der Stack zerschossen wäre. Soclhe Fehler fallen natürlich erst auf, wenn die zerstörte Stelle des Stacks benutzt wird, was sehr viel später sein kann. Nimm die Zeilen mal raus und du wirst sehen, es wird fehlerlos funktionieren.



  • ah alles klar. ich stand kurz aufm schlauch. indem ich

    *out_hans#=10;
    

    oder ähnliches mache, ändere ich eventuell einen bereich, in dem ans[#] gar nicht mehr liegt, sondern ein teil von meiner stringliste...
    und auch wenn ich das makro ändere auf:

    std::vector<double>::iterator out_##A=ans.end();
    

    (wobei ich mir nicht sicher bin, ob ans.end() wirklich auf das letzte element zeigt oder auf den bereich nach dem letzen... ans.end()-- ???)
    funktioniert es nicht - auf diesem wege komme ich wohl auf keine grünen zweig.

    danke für die antworten,

    thomas



  • Nimm std::list!



  • std::list hat den Nachteil, dass man nicht per index an die Elemente rankommt. Und bei so ner Frage-Antwort-Geschichte kann ich mir das schon vorstellen...

    Das Problem, in das du rennst, ist einfach, dass std::vector ein Array zum Halten der Daten verwendet. Wenn du da etwas anhängst, muss ein größeres Array erstellt werden, der alte Inhalt da rein kopiert, Element angehangen und altes Array zerstört werden. Die Adressen der einzelnen Werte im Array sind jetzt natürlich andere.

    Wenn du weiterhin std::vector verwenden willst, kannst du dir behelfen, indem du gleich nach dem Erstellen genügend Platz für deine ganzen Werte reservierst -> std::vector::reserve().
    Dabei bleiben Iteratoren gültig, solange ein insert() oder push_back() nicht die reservierte Größe überschreitet!



  • Ok, danke für die Tipps.
    Die Lösung mit der reservierte Größe klingt nur bedingt gut, denn wenn ich schon so arbeite, kann ich gleich mit herkömmlichen c-arrays arbeiten - in beiden Fällen habe ich Probleme, wenn ich ein Element außerhalb der reservierten Größe hinzufüge.
    ich habe das jedoch so gelöst, dass ich mit std::list arbeite, die iteratoren auf ans.begin() zeigen lasse und per std::advance(out_blubb,ans.size()-1) auf das richtige Element zeigen lasse.

    Vielen Dank nochmal für die Antworten.



  • Bei std::list werden die Iteratoren auf Elemente nicht ungueltig, wenn welche eingefuegt oder geloescht. Davon ausgenommen ist das geloeschte Element.



  • Reservist schrieb:

    Wenn du weiterhin std::vector verwenden willst, kannst du dir behelfen, indem du gleich nach dem Erstellen genügend Platz für deine ganzen Werte reservierst -> std::vector::reserve().
    Dabei bleiben Iteratoren gültig, solange ein insert() oder push_back() nicht die reservierte Größe überschreitet!

    Wobei die Lösung nicht wirklich schön ist... Wenn mal etwas mehr angehängt oder eingefügt wird, funktioniert der Kram nicht mehr, bzw. raucht ab und zeigt Müll an.

    Da würde ich auch die std::list bevorzugen, weil dort nur echt eingehängt bzw. angehängt wird. Die Objekte bleiben an der gleichen Adresse. Wenn du eine Speziallösung brauchst, ist so eine Liste auch relativ schnell selbst programmiert...


Anmelden zum Antworten