c++字符串容量在复制分配期间发生变化

标签 c++ string g++ capacity

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

最佳答案

当你这样做时:

s = s + "*";

你在做两件不同的事情:制作一个新的临时字符串,由连接到内容 s 末尾的 "*" 组成,然后复制分配s 的新字符串。

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

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

s += "*";

... 只做一件事,将 "*" 附加到 s 的末尾。因此,没有地方可以进行“优化”(如果发生了,那将是一种悲观,破坏了指数增长的全部目的)。

关于c++字符串容量在复制分配期间发生变化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24399519/

相关文章:

保留换行符的 C++ 预处理器字符串化?

c++ - 使用基类 :base in body 从类模板派生的类

string - 如何在 XQuery 中的一定数量的字符串字符后插入字符串?

linux - 无法在linux中编译opencv

g++ - Makefile 构建目录和依赖项列表

c++ - 我应该使用 cmake 搜索什么 Boost 包才能包含 Boost Function 的代码?

c++ - C++ 中抽象类作为类型,派生类作为实例

c - 如何在 C 中正确地 'printf' 一个整数和一个字符串?

Python(类型错误 : unsupported operand type(s) for Add: 'undefined' and 'str' )

c++ - 从 'char' 转换为非标量类型 'Vector<char>' 抛出错误,原因不明