std :: string是否保证不会自发回馈内存?

Mar*_*n G 31 c++ heap-memory stdstring language-lawyer

是否由标准保证,std::string如果从较小的字符串重新分配,则不会自发地回放分配的内存?

换一种说法:

std::string str = "Some quite long string, which needs a lot of memory";
str = "";
str = "A new quite long but smaller string"; // Guaranteed to not result in a heap allocation?
Run Code Online (Sandbox Code Playgroud)

我问,因为我依赖于此以避免堆碎片.

YSC*_*YSC 34

不保证任何.

[string.cons]/36定义分配const char*到一个std::string在移动指派,其定义是术语:

[string.cons]/32

basic_string& operator=(basic_string&& str)  noexcept(/*...*/)
Run Code Online (Sandbox Code Playgroud)

效果:移动分配为序列容器,但迭代器,指针和引用可能无效.

这表明委员会让实施在无效操作和更保守操作之间自由选择.并使事情更清楚:

[basic.string]/4

引用basic_­string序列元素的引用,指针和迭代器可能会被该basic_string对象的以下用法无效:

  • (4.1)作为任何标准库函数的参数,将非const basic_­string作为参数引用.
  • (4.2)调用非const成员函数,除了operator[],at,data,front,back,begin,rbegin,end,和rend.

我问,因为我依赖于此以避免堆碎片.

std::string将模板参数作为分配器.如果你真的担心可能的堆碎片,你可以编写自己的碎片,通过一些启发式方法可以有一个适合你需要的分配策略.

在实践中,我所知道的大多数实现都不会在您的问题的情况下重新分配内存.这可以通过测试和/或检查您的实现文档和最终源代码来检查.

  • 您可以想象,如果您将Gettysburg地址存储在字符串中,然后将其替换为"Hello World",那么这种保证将是多么不受欢迎(假定它已被赋予). (5认同)

bip*_*pll 13

CPP引用声明指向指向char的指针

将内容替换为s指向的以null结尾的字符串的内容,就好像是*this = basic_string(s),这涉及对Traits :: length的调用.

这个"好像"实际上归结为一个右值赋值,所以下面的场景很可能:

  1. 创建一个新的临时字符串.
  2. 字符串将其内容窃取为通过赋值给右值引用.

  • @ Cheersandhth.-Alf cppreference正在解释标准[`[string.cons]`](http://eel.is/c++draft/basic.string#string.cons-36) (6认同)
  • cppreference通常是可靠的,但引用的语句暗示有一个保证缓冲区替换,即bollocks.除此之外,它是一个很好的概念模型.但它只是简单*比标准的描述简单,在YSC的答案中引用,因此更为可取. (5认同)
  • @ Cheersandhth.-Alf真的吗?它说"好像",在标准中,总是意味着"关于可观察到的副作用,除了少数构造/破坏"之外. (5认同)