Frage zu sizeof



  • Das liegt daran, wie du den String initialisierst.



  • sizeof schrieb:

    std::string var= "\x41\x41\x00\x41\x41";
    

    Auch std::string wird durch \x00 Terminiert.

    Nein, bei der Initialisierung über einen const char* wird nur bis zum \0 kopiert (woher soll der Konstruktor auch wissen, dass das String-Literal noch länger ist?). Du kannst aber z.B.

    std::string var("\x41\x41\x00\x41\x41", 5);
    assert(var.length() == 5);
    

    sagen.


  • Mod

    sizeof schrieb:

    std::string var= "\x41\x41\x00\x41\x41";
    
    std::cout << var;
    
    std::string var[] = {"\x41\x41\x00\x41\x41"};
    
            for (int i=0;i<=sizeof(var);i++)
            {
                 std::cout<<var[i];
            }
    

    Gibt beides bei mir aus: AA

    Auch std::string wird durch \x00 Terminiert.

    Oho, Beweis durch Beispiel. Auch bekannt als "Das beweist überhaupt nichts". std::string braucht keine Nullterminierung zu haben und man darf sich darauf nicht verlassen, auch wenn bei deiner speziellen Implementierung vielleicht manchmal ein Nullzeichen folgt.



  • SeppJ schrieb:

    std::string braucht keine Nullterminierung zu haben und man darf sich darauf nicht verlassen, auch wenn bei deiner speziellen Implementierung vielleicht manchmal ein Nullzeichen folgt.

    Doch, man kann sich drauf verlassen, dass std::string nicht nullterminiert ist. Die Annahme, es sei doch so, beruht hier auf einer Fehlinterpretation, siehe die zwei Postings vor dir.


  • Mod

    Bashar schrieb:

    SeppJ schrieb:

    std::string braucht keine Nullterminierung zu haben und man darf sich darauf nicht verlassen, auch wenn bei deiner speziellen Implementierung vielleicht manchmal ein Nullzeichen folgt.

    Doch, man kann sich drauf verlassen, dass std::string nicht nullterminiert ist. Die Annahme, es sei doch so, beruht hier auf einer Fehlinterpretation, siehe die zwei Postings vor dir.

    Sicher? Ich bin mir ziemlich sicher, dass std::string auch eine Nullterminierung am Ende haben darf. Wäre zwar dumm das so zu implementieren, aber laut Standard dürfte nichts dagegen sprechen.



  • Ja, sicher. Lies es nach, 21.3§1:
    "the template class basic_string describes objects that can store a sequence consisting of a varying number of arbitrary char-like objects"

    Wenn du recht hättest, dürfte bei dem Code:

    std::string var("\x41\x41\x00\x41\x41", 5);
    assert(var.length() == 5);
    

    je nach Lust und Laune des Compilerherstellers die Assertion fehlschlagen.

    Der Konstruktor von std::string hat aber als Nachbedingung, dass size() bzw. length() gleich der übergebenen Länge ist.



  • Bashar schrieb:

    Ja, sicher. Lies es nach, 21.3§1:
    "the template class basic_string describes objects that can store a sequence consisting of a varying number of arbitrary char-like objects"

    Wenn du recht hättest, dürfte bei dem Code:

    std::string var("\x41\x41\x00\x41\x41", 5);
    assert(var.length() == 5);
    

    je nach Lust und Laune des Compilerherstellers die Assertion fehlschlagen.

    Der Konstruktor von std::string hat aber als Nachbedingung, dass size() bzw. length() gleich der übergebenen Länge ist.

    Ich glaube, du verstehst das mit dem Nullterminiert falsch. Das soll nicht bedeuten, dass bei einem \0 der String zu ende ist, sondern nur, dass hinter dem letzen gültigen Zeichen eine \0 stehen kann, aber nicht muss. Im String selber können beliebig viele \0 stehen und die ändern auch nichts an der Länge.


  • Mod

    Es soll ja auch nicht das Ende markieren. Die Implementierung darf doch am Ende des Speicherbereichs beliebige Zeichen anfügen. Es reicht ja, dass length, size & Co die richtigen Werte liefern. Auf diese Weise könnte man sich beispielsweise bei der Funktion c_str() das Anhängen der Null sparen.



  • SeppJ schrieb:

    Es soll ja auch nicht das Ende markieren.

    Doch, sonst ist es was anderes. Null-terminiert bedeutet, dass das Ende durch Null angezeigt wird.
    Was std::string außerhalb des zugreifbaren Bereichs anhängt, interessiert doch keinen. Da darf std::string es gerne eine Null anhängen, das ist auch gar nicht mal soo dumm, weil dann c_str() trivial (= performanter) implementiert werden kann.


  • Mod

    Ok, dann war das wohl nur ein Missverständnis wegen falscher Wortwahl. Genau das meinte ich nämlich.


  • Mod

    Bashar schrieb:

    SeppJ schrieb:

    Es soll ja auch nicht das Ende markieren.

    Doch, sonst ist es was anderes. Null-terminiert bedeutet, dass das Ende durch Null angezeigt wird.
    Was std::string außerhalb des zugreifbaren Bereichs anhängt, interessiert doch keinen. Da darf std::string es gerne eine Null anhängen, das ist auch gar nicht mal soo dumm, weil dann c_str() trivial (= performanter) implementiert werden kann.

    Die Komplexitätsanforderungen an c_str() bzw. data() erfordern das sogar.



  • Komplexitätsanforderungen an c_str oder data finde ich in C++98 nicht, wo stehen die?


  • Mod

    Finde ich zwar auch nicht, aber ein ganz fieser Implementierer könnte ja auch mehrere Kopien der Stringdaten halten. Oder immer schon ein paar Zeichen mehr reservieren, die aber nicht 0 gesetzt werden, sondern nur wenn tatsächlich c_str() benutzt wird. Damit könnte man auch ohne 0 am Ende der eigentlichen Daten eine konstante Zeitkomplexitat erreichen.


Anmelden zum Antworten