Reputation: 181
Is it possible to reserve space in a std::string and get a pointer to copy char data directly into it? I have to interface with a C library that returns strings by copying them into a char *. How can I set up a std::string so that the library can write directly into it, avoiding intermediate copies.
Hypothetical example how this could look like:
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
Upvotes: 4
Views: 1533
Reputation: 595412
Is it possible to reserve space in a std::string and get a pointer to copy char data directly into it?
Yes. Use its resize()
method to allocate the memory, and then use its data()
method (C++17 and later), or its operator[]
, to access that memory.
I have to interface with a C library that returns strings by copying them into a char *. How can I set up a std::string so that the library can write directly into it, avoiding intermediate copies.
Like this:
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);
}
Alternatively, std::string
has constructors which can allocate memory, too:
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);
Of course, this does require std::string
's memory block to be allocated contiguously, which is only guaranteed in C++11 and later (but in practice, is done in just about all known implementations). If you are not using C++11 or later, and really want to be standards compliant, then you should use an intermediate buffer, such as a std::vector
, eg:
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
}
Upvotes: 4