【问题标题】:C++ How to preserve string capacity when copyingC ++复制时如何保留字符串容量
【发布时间】:2016-08-05 07:54:27
【问题描述】:

EDIT(编辑历史中的原始帖子)

我可以用这个例子重现我的问题:

#include <string>
#include <vector>
using namespace std;

#define MAX_BUFFER 30

int main(int argc, char **argv) {

    vector<string> myVec = { "hey","asd","haha" };
    vector<string> clone;

    for (int i = myVec.size(); i--;) {
        myVec[i].reserve(myVec[i].size() + MAX_BUFFER);
        clone.push_back(myVec[i]);
    }

    return 0;
}

return 0; 之前添加一个断点。现在,检查 myVec 中的字符串并进行克隆。 他们的能力不一样!

【问题讨论】:

  • 你说的“预留空间不留”是什么意思,是什么让你这么想的?
  • 我编辑了这个例子,结果证明这不是问题(我的代码有点大)。但是现在,如果您运行第二个代码,您可以看到容量确实减少了。
  • @anon_user 不要试图在 C++ 中做 C。如果要将buffer 附加到std::string,请使用myString.append(buffer, bufferLen)std::string 将根据需要自动调整大小。
  • @Holt,我怀疑地球上是否有编译器能够优化它。我很可能会使用具有 size_t 长度和灵活的字符数组的结构。
  • @anon_user 你会感到惊讶。如果要添加大量元素并且知道要添加多少元素,则在 C++ 中保留容量很有用,因此您不想进行大量小的重新分配,而只想进行大的重新分配。如果您只打算追加一个缓冲区,那么您只需要一次重新分配,无论您是在 .append 之前使用 .reserve 还是让编译器在 append 中执行它都无关紧要。

标签: c++ string insert resize capacity


【解决方案1】:

复制std::string时不要求复制的容量相同。

$21.3.1.2/2 basic_string constructors and assignment operators [string.cons]:

Table 49 — basic_string(const basic_string&) effects
Element   Value
data()    points at the first element of an allocated copy of the array whose first element is pointed at by str.data()
size()    str.size()
capacity()    a value at least as large as size()

唯一的保证是字符串的容量至少与复制后的大小一样大。

这意味着你必须自己做:

for (int i = myVec.size(); i--;) {
    myVec[i].reserve(myVec[i].size() + MAX_BUFFER);
    clone.push_back(myVec[i]);
    clone.back().reserve(myVec[i].capacity());
}

【讨论】:

  • 这回答了我的问题,谢谢 :) 你碰巧知道我的编译器是否可以将它优化到只有一个分配?我使用 Visual Studio Community 2015 Update 3。
  • @anon_user 您将拥有两个字符串副本,因此编译器不能只进行一次分配。如果您不想保留旧副本,您应该move 字符串。
  • @anon_user 我不确定,但我认为答案是。你必须先构造std::string,然后再构造reserve
  • @Holt 我需要原件以供进一步参考。我的意思是如果复制部分只能是一个分配。编辑:@songyuanyao 好吧,我想我不得不求助于 char*
  • @anon_user 在大多数情况下它不会伤害任何东西。所以我建议你做性能评估,找出瓶颈,然后考虑如何改进。
【解决方案2】:

是的,字符串类有一个成员函数 String resize member funtion..

【讨论】:

    【解决方案3】:

    myString.resize(l) 不会改变字符串的容量,除非l 大于字符串的大小。只需致电myString.capacity() 并亲自查看。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-07-30
      • 2019-10-03
      • 2023-01-19
      • 1970-01-01
      • 1970-01-01
      • 2016-05-03
      相关资源
      最近更新 更多