1

在 C++ 标准中std:string遵循指数增长策略,因此我认为capacity()连接期间的字符串在必要时总是会增加。但是,当我测试时test.cpp,我发现在for循环中,只有每两次才会在分配期间capacity()缩回length()

为什么这种行为不取决于字符串的长度,而是取决于我更改字符串的频率?是某种优化吗?

以下代码使用g++ -std=c++11.

测试.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?
4

2 回答 2

1

当你这样做时:

s = s + "*";

您正在做两件不同的事情:创建一个新的临时字符串,包括"*"连接到 contents 的末尾s,然后将该新字符串复制分配给s.

不是缩水了+,是缩水了=。当从一个字符串复制分配到另一个字符串时,没有理由复制容量,只复制实际使用的字节。

您注释掉的代码执行此操作:

s += "*";

... 只做一件事,附加"*"s. 因此,“优化”无处可去(如果发生了,那将是一种悲观化,违背了指数增长的全部目的)。

于 2014-06-25T03:09:43.387 回答
1

C++ 标准实际上并没有说明capacity()当字符串被移动、分配等时会发生什么。这可能是一个缺陷。唯一的约束是那些可以从为操作指定的时间复杂度中导出的约束。

有关向量的类似讨论,请参见此处

于 2014-06-25T03:30:50.713 回答