Is it possible to initialize string with specific capacity?



  • SeppJ schrieb:

    std_string schrieb:

    std::string mystr;
    

    und anschließend die Capacity Abfrage bekomme ich 15 zurück.

    15 klingt verdächtig nach 2-4 Pointer minus 1.

    Entschuldige, aber ich kann mit deiner Äußerung nicht soviel anfangen, bzw. verstehe nicht auf was du hinaus willst.

    Wenn ich mir im Debug mode mein String Objekt ansehe, sehe ich eine Capacity von 15, wenn ich in die [Raw View] reingehe, sehe ich nach einigen Hierachieebenen einen char pointer der anscheinend ins Leere zeigt und ein _Alias char Array[16], dass an Position 0 mit '\0' und an Positionen 1-15 mit -52 initialisiert wurde.

    Der einzige Unterschied im Release Mode sind die Werte die im Array stehen, aber an Position [0] steht anscheinend immer ein '\0' was darauf hindeutet, dass dieses Array wirklich existiert bzw. der Speicher vom String Objekt wirklich allokiert wurde, oder nicht?



  • MSVC hält Strings bis zur Länge 15(+'\0') direkt im Objekt selber. Erst wenn längere Strings benötigt werden wird im Freispeicher alloziert.
    Die anderen Compiler dürften ähnliches machen.

    Nennt sich "Short String Optimization"(SSO).



  • Caligulaminus schrieb:

    MSVC hält Strings bis zur Länge 15(+'\0') direkt im Objekt selber. Erst wenn längere Strings benötigt werden wird im Freispeicher alloziert.
    Die anderen Compiler dürften ähnliches machen.

    Nennt sich "Short String Optimization"(SSO).

    😮 Ok, das wusste ich nicht. 😮

    Interessant, das bedeutet, dass jedes String Objekt ein char[15] Array mit sich herumschleppt auch, wenn es bei size > 16 überhaupt nicht mehr benötigt wird.

    Ich habe gerade bei mir MSVC2013 geguckt und bei mir ist es wirklich so.

    Ich sehe bei size > 16 den Char Pointer und deep in der Hierachie , dass nicht mehr benutzte char array.



  • std_string schrieb:

    Interessant, das bedeutet, dass jedes String Objekt ein char[15] Array mit sich herumschleppt auch, wenn es bei size > 16 überhaupt nicht mehr benötigt wird.

    Wenn Freispeicher verwendet wird, wird der Platz des internen Arrays für Zeiger und Kapazität(size_t oder auch ein Zeiger) verwendet. Unter x64 wird so nichts vergeudet. Unter x64 gehen - glaube ich - 8 Byte verloren, ja. Aber das ist ein kleiner Preis für ein gespartes new (oder wie dein std::string auch immer den Speicher holt).


  • Mod

    Caligulaminus schrieb:

    für ein gespartes new (oder wie dein std::string auch immer den Speicher holt).

    Da gibt es übrigens keinen Interpretationsspielraum. std::string ist die Instanzierung des basic_string-Templates mit char als Datentyp und dem Defaultallokator als Allokator. Und dieser läuft letztlich auf ::operator new hinaus.



  • SeppJ schrieb:

    Caligulaminus schrieb:

    für ein gespartes new (oder wie dein std::string auch immer den Speicher holt).

    Da gibt es übrigens keinen Interpretationsspielraum. std::string ist die Instanzierung des basic_string-Templates mit char als Datentyp und dem Defaultallokator als Allokator. Und dieser läuft letztlich auf ::operator new hinaus.

    Wie ist das denn genau definiert? Müsste ja so sein, dass es ein implementationsdefiniertes, festes N geben muss, sodass gilt: ( size() >= N) impliziert ( data() kommt vom Allocator). Das würde dann die SSO erlauben.


  • Mod

    TyRoXx schrieb:

    SeppJ schrieb:

    Caligulaminus schrieb:

    für ein gespartes new (oder wie dein std::string auch immer den Speicher holt).

    Da gibt es übrigens keinen Interpretationsspielraum. std::string ist die Instanzierung des basic_string-Templates mit char als Datentyp und dem Defaultallokator als Allokator. Und dieser läuft letztlich auf ::operator new hinaus.

    Wie ist das denn genau definiert? Müsste ja so sein, dass es ein implementationsdefiniertes, festes N geben muss, sodass gilt: ( size() >= N) impliziert ( data() kommt vom Allocator). Das würde dann die SSO erlauben.

    as-if.
    Wird SSO überhaupt mit eigenen Allokatoren angewandt?



  • TyRoXx schrieb:

    SeppJ schrieb:

    Caligulaminus schrieb:

    für ein gespartes new (oder wie dein std::string auch immer den Speicher holt).

    Da gibt es übrigens keinen Interpretationsspielraum. std::string ist die Instanzierung des basic_string-Templates mit char als Datentyp und dem Defaultallokator als Allokator. Und dieser läuft letztlich auf ::operator new hinaus.

    Wie ist das denn genau definiert? Müsste ja so sein, dass es ein implementationsdefiniertes, festes N geben muss, sodass gilt: ( size() >= N) impliziert ( data() kommt vom Allocator). Das würde dann die SSO erlauben.

    §21.4.1/4 schrieb:

    [...]Every object of type basic_string<charT,traits, Allocator> shall use an object of type Allocator to allocate and free storage for the contained charT objects as needed.



  • Nathan schrieb:

    §21.4.1/4 schrieb:

    [...]Every object of type basic_string<charT,traits, Allocator> shall use an object of type Allocator to allocate and free storage for the contained charT objects as needed.

    Das verbietet SSO. Und jetzt?


  • Mod

    TyRoXx schrieb:

    SeppJ schrieb:

    Caligulaminus schrieb:

    für ein gespartes new (oder wie dein std::string auch immer den Speicher holt).

    Da gibt es übrigens keinen Interpretationsspielraum. std::string ist die Instanzierung des basic_string-Templates mit char als Datentyp und dem Defaultallokator als Allokator. Und dieser läuft letztlich auf ::operator new hinaus.

    Wie ist das denn genau definiert? Müsste ja so sein, dass es ein implementationsdefiniertes, festes N geben muss, sodass gilt: ( size() >= N) impliziert ( data() kommt vom Allocator). Das würde dann die SSO erlauben.

    Das folgt schon aus den Komplexitätsgarantien, z.B. für swap.
    SSO ist im Übrigen für normale Container nicht zulässig, da dort Iteratoren auf Elemente (gilt nicht für end) bei swap stabil bleiben müssen.



  • TyRoXx schrieb:

    Nathan schrieb:

    §21.4.1/4 schrieb:

    [...]Every object of type basic_string<charT,traits, Allocator> shall use an object of type Allocator to allocate and free storage for the contained charT objects as needed.

    Das verbietet SSO. Und jetzt?

    Nein? Es sagt nur das, wenn man Speicher braucht drn Allokator nutzen soll.
    Bei SSO braucht man keinen.


Anmelden zum Antworten