【问题标题】:std::string shrink_to_fit corrupts string [duplicate]std::string shrink_to_fit 损坏字符串 [重复]
【发布时间】:2020-03-02 06:26:09
【问题描述】:

所以我有这个由 C 样式函数填充的 std::string 对象,例如 strcpy。该函数可以返回 10-100 个字符之间的任意字符,所以我在字符串中保留 100 个。

但是使用&buf[0] 可以,但是当我尝试shrink_to_fit() 时,字符串会损坏。我怎样才能避免这种情况?

std::string buf;
buf.reserve(100);
//example of the function that can write to a buffer with 10-100 characters.
strcpy(&buf[0], "Hello");
buf.shrink_to_fit();
std::cout << buf << std::endl;

【问题讨论】:

  • reserve 不会更改 size。你只是做错了。你可能想要resize。另外,为什么要混合 C 风格的字符串处理和 C++ string 对象?

标签: c++ string stl buffer


【解决方案1】:

reserve() 设置字符串的容量,而不是其大小。两种不同的东西。 容量 是分配了多少内存来保存字符。 size 是分配的内存中实际有效的字符数。

shrink_to_fit() 缩小 容量 以匹配当前 大小。但是您的字符串的 size 始终为 0,因此无论您是否调用 shrink_to_fit(),该字符串实际上都是空的,没有损坏。打印std::string 会打印最多其大小的字符,而不是其容量

你需要使用resize()而不是reserve(),例如:

std::string buf;
buf.resize(100);
//example of the function that can write to a buffer with 10-100 characters.
strcpy(&buf[0], "Hello");
buf.resize(strlen(buf.c_str()));
buf.shrink_to_fit();
std::cout << buf << std::endl;

话虽如此,shrink_to_fit() 不是必需 做任何事情,它是实现定义的。您可以考虑使用单独的缓冲区将字符读入,然后从该缓冲区构造您的 std::string,例如:

std::array<char, 100> buf;
//example of the function that can write to a buffer with 10-100 characters.
strcpy(buf.data(), "Hello");
std::string str(buf.data(), strlen(buf.data()));
std::cout << str << std::endl;

或者,在 C++17 及更高版本中,您可以改用std::string_view,例如:

std::array<char, 100> buf;
//example of the function that can write to a buffer with 10-100 characters.
strcpy(buf.data(), "Hello");
std::string_view sv(buf.data(), strlen(buf.data()));
std::cout << sv << std::endl;

【讨论】:

  • std::string str(buf.data(), strlen(buf.data())); 有点冗长,std::string 构造函数默认只传递指针时会这样做
  • @Slava True,但这只是一个例子。我们不知道 OP 实际调用什么 C 样式函数来获取字符数据,或者该数据是否以空值结尾。也许函数返回写入 OP 缓冲区的字符数,我们不知道。所以我写了我的例子来展示如何在给定指针和计数的情况下构造一个std::string(_view),以防万一。
  • 好的,谢谢。我需要使用GetTempPathW winapi 函数。但这些似乎是很好的答案。
  • @ArushAgarampur 在这种情况下,GetTempPathW() 确实输出了一个以空字符结尾的字符串,但它也返回了输出的字符数,不包括空字符终止符。此外,要将GetTempPathW() 的输出存储到C++ 字符串中,您需要使用std::wstring(_view) 而不是std::string(_view),除非您计划将输出的wchar_t 数据转换为ANSI 或UTF-8。
猜你喜欢
  • 2016-12-02
  • 2018-06-05
  • 1970-01-01
  • 1970-01-01
  • 2013-06-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-05-07
相关资源
最近更新 更多