string::resize



  • hallo leute

    unter VS2013 hab ich folgenden code verwendet:

    inline auto get_window_text(const window_handle &h) noexcept -> std::wstring
    {
       std::size_t len = static_cast<int>(SendMessage(h.handle(), WM_GETTEXTLENGTH, 0, 0));
       std::wstring str;
       str.reserve(len + 1);
       SendMessage(h.handle(), WM_GETTEXT, (WPARAM)len + 1, (LPARAM)&str[0]);
       str.resize(len); // (1)
    
       return str;
    }
    

    hier wird einfach nur die eingabe eines edit-controls in einen string kopiert.
    unter VS2015 funktioniert der code nicht mehr so wie er soll.
    in der zeile (1) wird der string mit '\0' ueberschrieben. warum ?
    ich war der meinung das ich dem string mit resize sage, wie lange er ist. scheinbar lieg ich da falsch

    im grund muss ich folgendes machen:
    () textlaenge abfragen = len
    (
    ) speicher im string reservieren: len + 1 // + 1 fuer abschliesendes '\0'
    () das control kopiert den text in den string ab adresse &str[0]
    (
    ) ich muss dem string sagen das der inhalt len zeichen lang ist // machte ich bisher mit resize

    wie macht man es richtig ?

    Meep Meep



  • resize statt reserve sollte gehen.



  • danke funktioniert. aber warum ?
    weshalb muss ich jetzt meinen source aendern?
    was habe ich an reserve missverstanden ?

    Meep Meep



  • reserve verändert die Kapazität des strings. Falls du schon weißt, dass du in nächster Zeit ständig die Größe des Strings verändern wirst, zum Beispiel durch resize oder append oder ähnliches, muss nicht jedes mal neu Speicher angefordert werden (sofern sich der string vergrößert). Du würdest hier eine große Kapazität anfordern. Diese ist sozusagen die potentielle Größe des strings, die tatsächliche wird über size() wiedergegeben und unter anderem über resize gesetzt.
    Du kannst dir reserve als Hinweis für die Speicherverwaltung des strings vorstellen. Aber auch, wenn der Speicher da ist, darfst du da trotzdem nicht einfach reinschreiben. Das überwacht der string.



  • Meep Meep schrieb:

    danke funktioniert. aber warum ?

    Hast du dir die Doku zu resize mal durchgelesen?

    Meep Meep schrieb:

    weshalb muss ich jetzt meinen source aendern?

    Weil er Fehler enthält?



  • Auf den "reservten" darfst du nicht zugreifen, nur auf den "resizten". Der SendMessage Aufruf macht daher Unsinn.



  • Auf den "reservten" darfst du nicht zugreifen, nur auf den "resizten". Der SendMessage Aufruf macht daher Unsinn.



  • also wenn ich das richtig verstanden habe, ist folgendes abgelaufen:
    mit reserve hab ich speicher geholt. den ich aber noch nicht beutzen durfte, weil ich mit resize noch keine groesse vereinbart hatte.
    nach dem ich in den reservierten speicher geschrieben hatte hat resize den speicher erstmals initialisiert und dadurch den kopierten inhalt mit '\0' ueberschrieben.

    nachdem das mit VS2013 noch nicht passiert ist, hat resize in 2013 den speicher nicht mit '\0' initialisiert.

    gibt es eine moeglichkeit resize das initialisieren zu verbieten ? sonst wird der speicher ja doppelt beschrieben. einmal mit '\0' und dann mit meinem textinhalt.

    Meep Meep



  • Meep Meep schrieb:

    gibt es eine moeglichkeit resize das initialisieren zu verbieten ? sonst wird der speicher ja doppelt beschrieben. einmal mit '\0' und dann mit meinem textinhalt.

    Irgendeinen Tod musst Du sterben...
    Aber nimm doch gleich einen passenden C'tor von std::string und verzichte auf resize() .


Log in to reply