【问题标题】:Is it possible to reserve and copy into a std::string directly?是否可以直接保留并复制到 std::string 中?
【发布时间】:2020-08-27 16:51:23
【问题描述】:

是否可以在 std::string 中保留空间并获得将 char 数据直接复制到其中的指针? 我必须与通过将字符串复制到 char * 中返回字符串的 C 库进行交互。 如何设置 std::string 以便库可以直接写入其中,避免中间副本。

假设示例如下:

std::string mystring;
int strlen = foolib_get_string_size(fooval);
mystring.size(strlen); // assuming size() with arg exists and does reserve() and set size
foolib_string_to_char_buffer(fooval, mystring.data(), strlen); // abusing data() method for writing

【问题讨论】:

  • mystring.size(strlen);...你想要的是mystring.resize(strlen);
  • @g19fanatic:内容确实是同一个问题,但标题具有误导性(暗指 existing char * 数组)。这就是它没有出现在搜索结果中的原因。
  • 虽然你的标题对我来说不太清楚。

标签: c++ string performance copy buffer


【解决方案1】:

是否可以在 std::string 中保留空间并获取指针以将 char 数据直接复制到其中?

是的。使用其resize() 方法分配内存,然后使用其data() 方法(C++17 及更高版本)或其operator[] 访问该内存。

我必须与一个 C 库交互,该库通过将字符串复制到 char * 中来返回字符串。如何设置 std::string 以便库可以直接写入其中,避免中间副本。

像这样:

std::string mystring;
int strlen = foolib_get_string_size(fooval);
if (strlen > 0)
{
    mystring.resize(strlen); // -1 if strlen includes space for a null terminator
    foolib_string_to_char_buffer(fooval, mystring.data()/*&mystring[0]*/, strlen);
}

另外,std::string 也有可以分配内存的构造函数:

int strlen = foolib_get_string_size(fooval);
std::string mystring(strlen, '\0'); // -1 if strlen includes space for a null terminator
if (strlen > 0)
    foolib_string_to_char_buffer(fooval, mystring.data()/*&mystring[0]*/, strlen);

当然,这确实需要std::string 的内存块被分配连续,这仅在 C++11 及更高版本中得到保证(但实际上,几乎所有已知的实现)。如果您没有使用 C++11 或更高版本,并且确实希望符合标准,那么您应该使用中间缓冲区,例如 std::vector,例如:

std::string mystring;
int strlen = foolib_get_string_size(fooval);
if (strlen > 0)
{
    std::vector<char> myvector(strlen);
    foolib_string_to_char_buffer(fooval, &myvec[0], strlen);
    mystring.assign(&myvec[0], strlen); // -1 if strlen includes space for a null terminator
}

【讨论】:

  • 谢谢!因此,单行答案似乎是:原则上是,从 C++11 到 &mystring[0],正式是,从 C++17 到 data() .
  • @diemo 更像,原则上是在 C++11 之前和 正式是从 C++11 到 &amp;mystring[0],以及 从 C++17 到 mystring.data(),正式支持。
猜你喜欢
  • 1970-01-01
  • 2017-10-28
  • 1970-01-01
  • 2012-12-13
  • 2010-12-21
  • 1970-01-01
  • 1970-01-01
  • 2019-03-19
  • 1970-01-01
相关资源
最近更新 更多