Thinking in C++ Łancuchy Znakowe

0

Właśnie uczę się z drugiego tomu thinking in c++. Nie potrafię zrozumieć jednej rzeczy. Dokładnie chodzi o rezerwacje pamięci w string.

Cytuje "Kiedy testowaliśmy powyższy przykład w jednej z implementacji, okazało się, że realokacja pojawia się na granicach parzystych słów (czyli dla wielkości danych typu int) przy zachowaniu jednego bajta.

Moje pytanie, o co dokładnie chodzi w tym co jest w nawiasie a mianowicie "czyli dla wielkości danych typu int". Bo rozumiem ze jeżeli realokacja pojawiała się na granicach parzystych słów czyli co dwa bajty, ale jak maja się te dwa bajty do "czyli dla wielkości danych typu int"

IMG_20220802_122009.jpg
BR, Patryk

3

Thinking in C++ nie jest raczej uznawana za dobrą książkę... W tym miejscu zupełnie niepotrzebnie próbuje wyjaśniać implementację realokacji pamięci dla std::string na podstawie jakiegoś kodu - wyciągając raczej błędne wnioski.

2

Masz prosty przykład:

#include <string>
#include <iostream>

int main()
{
    std::string txt="";
    
    for (int num=0; num<100; ++num) 
    {
      std::cout << txt.capacity() << " " << txt.size() << std::endl;
      txt.append(1, 'a');
    }
}

Jak widać - na moim komputerze string startuje z "pojemnością" 15 znaków, po przekroczeniu tej pojemności alokowane jest dwa razy więcej pamięci. U Ciebie może być inaczej.

15 0
15 1
15 2
...
15 14
15 15
30 16
30 17
30 29
...
30 30
60 31
...
60 59
60 60
120 61
...
120 99
3

Bo rozumiem ze jeżeli realokacja pojawiała się na granicach parzystych słów czyli co dwa bajty

No właśnie nie. Tutaj angielska wersja byłaby bardziej przejrzysta (edit jednak nie jest patrz post niżej). Za słowo, WORD przyjęło się uznawać alias na short który zwyczajowo ma 16 bitów, czyli dwa bajty. na granicy przystych słów czyli co cztery bajty, co zwyczajowo jest rozmiarem int. Wtedy fragment czyli dla wielkości danych typu int ma sens.

(edit)
Bardzo nie podoba mi się ten fragment. Wyjaśnienie dlaczego dalej w temacie.

2
several napisał(a):

Bo rozumiem ze jeżeli realokacja pojawiała się na granicach parzystych słów czyli co dwa bajty

No właśnie nie. Tutaj angielska wersja byłaby bardziej przejrzysta. Za słowo, WORD przyjęło się uznawać alias na short który zwyczajowo ma 16 bitów, czyli dwa bajty. na granicy przystych słów czyli co cztery bajty, co zwyczajowo jest rozmiarem int. Wtedy fragment czyli dla wielkości danych typu int ma sens.

To jest z angielskiej wersji:

The exact fashion in which the string member functions will allocate space for your data is
dependent on the implementation of the library. When one implementation was tested with
the example above, it appeared that reallocations occurred on even word boundaries, with one
byte held back. The architects of the string class have endeavored to make it possible to mix
the use of C char arrays and C++ string objects, so it is likely that figures reported by
StrSize.cpp for capacity reflect that in this particular implementation, a byte is set aside to
easily accommodate the insertion of a null terminator.
1

Aha, czyli nie jest bardziej przejrzysta. Bardzo nie podoba mi się ten fragment. WORD jest czysto windowsowym wynalazkiem i początkujący czytelnik ma prawo tego nie znać, do tego tak szczegółowe omawianie implementacji, która jest już nieaktualna w niczym nie pomaga.

Do tego nie ma gwarancji, że w int zmieszczą się dwa short, to są typy bez gwarancji rozmiaru a jedyne co o nich wiemy to to, że short ma mieć przynajmniej 16 bitów a int przynajmniej 32 bity (na maszynach 32/64 bit).

Bardzo słaby fragment książki - autor zakłada, że początkujący czytelnik będzie wiedział to wszystko i zrozumie co jest napisane.

1

Ok, super, bardzo wam dziekuje za wyjasnienie, sam bym faktycznie na to nie wpadł. Poszukam innej książki do nauki tutaj na forum.

1

W ramach ciekawostki - po drobnych zmianach kodu ( https://godbolt.org/z/fKnebqhxE )

Wyniki dla:
MSVC:

15 0
31 16
47 32
70 48
105 71
157 106
235 158
352 236
528 353
792 529
1188 793
1782 1189
2673 1783

gcc, clang, icc

15 0
30 16
60 31
120 61
240 121
480 241
960 481
1920 961
3840 1921
4

@Bartłomiej Golenko: std::string jest implementowany w bibliotece, więc zestawienie razem trzech kompilatorów gcc, clang i icc w sytuacji w której wszyskie najwyraźniej używają libstdc++ jest mylące, bo sugeruje, że trzy osobne implementacje dają te same wyniki a tak na prawdę używasz jednej implementacji dla wszystkich trzech. Twój kod skompilowany clangiem, który pod spodem używa libc++ (implementacji od LLVM) daje takie wyniki

22 0
47 23
95 48
191 96
383 192
767 384
1535 768
3071 1536

Projekt do testów https://github.com/pdy/scrapyard/tree/master/StdStringRealloc

1 użytkowników online, w tym zalogowanych: 0, gości: 1