C++字符串使用最大缓冲区分配?

Viv*_*oel 6 c++ string stl

我宣布一个变量 string s;

s = "abc";现在它有3个字符缓冲区.

s = "abcd" 它有4个字符的缓冲区.

现在是第三个声明之后

s = "ab" 问题是它会保留4个字符的缓冲区还是会重新分配2个字符的缓冲区?

如果它将分配2个字符缓冲区有任何方法我可以告诉它保持分配的最大缓冲区.

那么它是否保留了最大大小的缓冲区?

s = "ab"
s="abc"
s="a"
s="abcd"
s="b"
Run Code Online (Sandbox Code Playgroud)

现在它应该保持4的缓冲区.

那可能吗?

Bo *_*son 10

字符串将在分配后保留其缓冲区,并且只有在需要更大的缓冲区时才重新分配.它也可能以初始缓冲区大小大于3或4开始.

您可以使用capacity()成员函数检查分配的大小.


詹姆斯在下面发表评论后,我仍然相信我的答案对于问题中给出的例子是正确的.

但是,对于引用计数实现这样的序列

s = "some rather long string...";

std::string t = "b";
s = t;
Run Code Online (Sandbox Code Playgroud)

如果实现决定在和之间共享内部缓冲区s.capacity(),t.capacity()则设置为等于.st


Arm*_*yan 7

s ="ab"问题是它会保留4个字的缓冲区还是重新分配2个字缓冲区?

它不会重新分配缓冲区.我不知道它是否在标准中提到过,但我所见过的所有实现只有在需要增加容量时才会发出重新分配.永远不要减少.即使你有一个包含4个字符的字符串并且呼叫.resize(2).reserve(2)容量不会改变.为了强制字符串(或容器)重新分配内存以适应确切的大小,有一个简单的swap技巧

s.swap(string(s));
Run Code Online (Sandbox Code Playgroud)

这里发生了什么?您可以创建一个临时的s,它的容量将完全相等,s.size()然后将其与原始字符串交换.临时的析构函数将释放所有必要的资源.

同样,我并不认为这是标准的,但我见过的所有实现都有这种行为.

  • 这取决于实现:如果为其分配新的字符串,g ++将更改容量,容量更小,VC++通常会使用固定容量集中的最小容量.(我怀疑你在想'std :: vector`;你所描述的是g ++和VC++的行为,我无法相信你们都没有看过这些.) (2认同)