复制分配期间c ++字符串容量更改

时间:2014-06-25 03:03:33

标签: c++ string g++ capacity

在C ++标准中std:string遵循指数增长策略,因此我认为在连接期间字符串的capacity()将在必要时始终增加。但是,当我测试test.cpp时,我发现在for循环中,仅每两次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?

2 个答案:

答案 0 :(得分:1)

执行此操作时:

s = s + "*";

你正在做两件事:创建一个新的临时字符串,由"*"连接到内容s的末尾,然后将新字符串复制分配给{{1} }。

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

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

=

...只做一件事,将s += "*"; 追加到"*"的末尾。因此,“优化”无处可去(如果发生这种情况,那将是悲观化,从而无法实现指数增长的全部目的。)

答案 1 :(得分:1)

实际上,C ++标准并未对移动,分配字符串等时capacity()发生什么事情做出这样的规定。这可能是一个缺陷。唯一的约束是可以从为操作指定的时间复杂度中导出的约束。

See here关于向量的类似讨论。