如何直接从char*数组创建一个std :: string而不复制?

fyh*_*ang 18 c++ string buffer stl

假设我有一个字符数组,我已在堆上分配,并且我想将其转换为std :: string.目前我正在做以下事情:

char *array = new char[size];
WriteIntoArray(array, size);
std::string mystring(array);
delete[] array;
return mystring; // or whatever
Run Code Online (Sandbox Code Playgroud)

从我在互联网上读到的内容(http://www.cplusplus.com/reference/string/string/string/),字符串构造函数执行我传递它的缓冲区的副本,让我释放缓冲区(稍后,该字符串释放其内部缓冲区).我想要做的是分配我的缓冲区,将它的控制转移到字符串,然后在它被破坏时让它释放我的缓冲区.

这个问题从字符*初始化的std :: string没有副本看起来前途无量,但我的代码依赖于(在上面的例子中"WriteIntoArray")API调用它必须写入字符数组,所以我必须创建一个C风格char*buffer,并且不能将我的代码转换为仅使用内置字符串操作(这是建议的答案).

有没有一些标准的方法来做到这一点,或者我应该写我自己的字符串类(呃)?谢谢!

Joh*_*eek 16

如果您正在使用符合标准的C++ 0x实现,或者保证连续存储的许多C++库之一std::string,那么您可以char*直接指向您使用的存储std::string.

例如:

std::string mystring;
mystring.resize(size);
WriteIntoArray(&mystring[0], size);
return mystring;
Run Code Online (Sandbox Code Playgroud)

但是,您可能必须仔细考虑null终止符.

  • @SørenLøvborg是的,在C++ 11中是允许的.围绕这个有很多神秘的措辞,这几乎归结为修改null终止符是非法的,并且通过data()或c_str()指针修改任何内容是非法的,但是通过&str [0]有效.http://stackoverflow.com/a/14291203/5696 (3认同)
  • 你不能使用reserve(),你必须使用resize().然后在调用后找出适当的resize(). (2认同)
  • `reserve`需要`调整大小`."仔细考虑空终结者"究竟意味着什么?是否保证`&mystring [0]`指向的数组是否必须以空值终止?`std :: string`是否负责确保这样的终结符存在?如果`WriteIntoArray`写了一个空终止符,它应该被删除吗?(我问,因为我不知道`std :: string`保证和要求什么.) (2认同)
  • 大概是`WriteIntoArray`放置一个空终止符,在调用之后需要删除它; 你可能想在返回之前添加`mystring.resize(size-1);`.如果它没有添加null,那么你应该使用`vector <char>`而不是`string`. (2认同)

小智 12

您可以实现自己的std :: allocator,而不是为您的字符串分配新内存,将您已实例化的区域用作源.

然后,您应该使用分配器实例化您的std :: string.

http://www.codeproject.com/Articles/4795/C-Standard-Allocator-An-Introduction-and-Implement


Mar*_*ork 5

你不能std :: string拥有指针,因此将数据复制到它分配的空间.

你能做的是:

std::string  mystring(size, ' ');
WriteIntoArray(&mystring[0], size);
return mystring; // or whatever
Run Code Online (Sandbox Code Playgroud)