изменение емкости строки c ++ при назначении копии

В стандарте C ++ std:string следует политике экспоненциального роста, поэтому я полагаю, capacity() строки во время конкатенации всегда будет увеличиваться при необходимости. Тем не менее, когда я тестирую test.cppЯ обнаружил, что в цикле, только каждые два раза будет ли capacity() быть возвращенным к length() во время назначения.

Почему это поведение не зависит от длины строки, а зависит от того, как часто я меняю строку? Это какая-то оптимизация?

Следующие коды проверены с g++ -std=c++11,

test.cpp:

#include <iostream>
int main(int argc, char **argv) {
std::string s = "";
for (int i = 1; i <= 1000; i++) {
//s += "*";
s = s + "*";
std::cout << s.length() << " " << s.capacity() << std::endl;
}
return 0;
}

И вывод будет таким:

1 1
2 2
3 4
4 4
5 8
6 6    // why is capacity shrunk?
7 12
8 8    // and again?
9 16
10 10  // and again?
11 20
12 12  // and again?
13 24
14 14  // and again?
15 28
16 16  // and again?
17 32
...
996 996
997 1992
998 998  // and again?
999 1996
1000 1000  // and again?

1

Решение

Когда вы делаете это:

s = s + "*";

Вы делаете две разные вещи: создаете новую временную строку, состоящую из "*" соединены в конец содержимого sи затем скопировать, присвоив эту новую строку s,

Это не + это сокращается, это =, При назначении копирования из одной строки в другую нет смысла копировать емкость, а только фактически используемые байты.

Ваш закомментированный код делает это:

s += "*";

… делает только одну вещь, добавляя "*" на конец s, Так что «оптимизации» некуда (если это произойдет, это будет pessimization, победить всю цель экспоненциального роста).

1

Другие решения

Это на самом деле не соответствует стандарту C ++, что происходит с capacity() когда строки перемещаются, присваиваются и т. д. Это может быть дефектом. Единственными ограничениями являются те, которые выводятся из временной сложности, указанной для операции.

Посмотреть здесь для аналогичного обсуждения о векторах.

1