std::string capacity und assign



  • Hallo,

    weiß jemand, wie sich std::string::assign bezüglich der capacity verhalten soll? Ich finde so spontan nichts im C++-Standard.

    Also was muß laut Standard hier raus kommen:

    std::string s;
    s.reserve(512);
    s.assign("Hallo");
    std::cout << s.capacity() << std::endl;
    

    Ich habe hier Compiler. Die eine gibt 512 aus und die andere 31. Ich halte die 31 für nicht Standard-Konform. Meiner Meinung Nach muss die Ausgabe auf jeden fall eine Zahl >= 512 ausgeben. Sehe ich das richtig?



  • tntnet schrieb:

    Meiner Meinung Nach muss die Ausgabe auf jeden fall eine Zahl >= 512 ausgeben. Sehe ich das richtig?

    Seh ich auch so. Steht allerdings nicht explizit im Standard, zumindest habe ich nichts dergleichen finden können. 🙂



  • capacity muß zumindest so groß sein, wie size. Ist in beiden Varianten schon mal gegeben.
    Laut Draft muß aber nach dem reserve das capacity gleich oder größer als das reserve-Argument sein. Würde sagen, 31 ist falsch.


  • Administrator

    Dreh mal das assign und capacity um. Ich bin mir ziemlich sicher, dass dann beide 512 ausgeben werden.
    Wenn ich mich recht entsinne, dann gab es doch was, dass der string seine grösse laufend anpassen darf. Also falls weniger Speicher benötigt wird, als reserviert ist, dann darf der string seinen Speicher verkleinern.

    Ist vielleicht nicht immer praktisch, aber das darf wohl jeder selber entscheiden, wie er das umsetzen will. Hat natürlich schon was, wenn du einen string mit 512 Bytes verwendest und danach nur ein "Hallo" zuweist. In einigen Fällen könnte das Speicherschonender sein. Aber naja, ist wohl ein Streitpunkt.

    Grüssli



  • Dravere schrieb:

    Dreh mal das assign und capacity um. Ich bin mir ziemlich sicher, dass dann beide 512 ausgeben werden.
    Wenn ich mich recht entsinne, dann gab es doch was, dass der string seine grösse laufend anpassen darf. Also falls weniger Speicher benötigt wird, als reserviert ist, dann darf der string seinen Speicher verkleinern.

    Ist vielleicht nicht immer praktisch, aber das darf wohl jeder selber entscheiden, wie er das umsetzen will. Hat natürlich schon was, wenn du einen string mit 512 Bytes verwendest und danach nur ein "Hallo" zuweist. In einigen Fällen könnte das Speicherschonender sein. Aber naja, ist wohl ein Streitpunkt.

    Grüssli

    Wenn ich nach dem assign ein reserve(512) aufrufe, erhalte ich eine capacity von 543. Das ist korrektes Verhalten, da reserve hier mindestens 512 bytes reserviert hat.

    Zum Hinweis: Es geht hier um einen Codeausschnitt. Hier folgen natürlich noch weitere append -Aufrufe, die bei einer capacity von 31 unnötigerweise zusätzliche Allokationen auslösen, obwohl ich dem std::string mitgeteilt habe, dass der String grösser wird.



  • tntnet schrieb:

    Hier folgen natürlich noch weitere append -Aufrufe, die bei einer capacity von 31 unnötigerweise zusätzliche Allokationen auslösen,...

    Wäre hier nicht ein Stream besser geeignet?



  • asc schrieb:

    tntnet schrieb:

    Hier folgen natürlich noch weitere append -Aufrufe, die bei einer capacity von 31 unnötigerweise zusätzliche Allokationen auslösen,...

    Wäre hier nicht ein Stream besser geeignet?

    Nein. Am Stream würde man das mögliche Fehlverhalten beim std::string nicht sehen. Damit könnte ich meine Frage nicht erläutern 🙄 .


  • Administrator

    tntnet schrieb:

    Nein. Am Stream würde man das mögliche Fehlverhalten beim std::string nicht sehen. Damit könnte ich meine Frage nicht erläutern 🙄 .

    Ich habe schon mal gesagt, dass es womöglich kein Fehlverhalten ist, weil du noch ein assign dazwischen hast. Mir ist nicht bekannt, dass die capacity erhalten bleiben muss, nach einem assign Aufruf. Zudem was bringt es dir, wenn du wüsstest, dass es ein Fehlverhalten ist?

    @asc,
    Wenn er nur Strings verwendet und keine Konvertierungen durchführen will, dann rate ich von den Streams ab. Ich habe das Anhängen von Daten bei einem stringstream mit dem Anhängen von Daten bei einem string verglichen (Dinkumware), da war der normale string mit dem operator += deutlich schneller und das ohne vorher ein capacity Aufruf durchzuführen!

    Grüssli


Anmelden zum Antworten