I have a function f
returning a char*
. The function documentation says:
The user must delete returned string
I want to construct a std::string
from it. The trivial things to do is:
char* cstring = f();
std::string s(cstring);
delete cstring;
Is it possibile to do it better using C++ features? I would like to write something like
std::string(cstring)
avoiding the leak.
For non-union class types ( class and struct ), the move constructor performs full member-wise move of the object's bases and non-static members, in their initialization order, using direct initialization with an xvalue argument. If this satisfies the requirements of a constexpr constructor, the generated move constructor is constexpr .
// Assign C string to std:string directly std::cout << mystring << ' '; Show activity on this post. Thanks for contributing an answer to Stack Overflow! Please be sure to answer the question. Provide details and share your research! But avoid … Asking for help, clarification, or responding to other answers.
It is not obligated to move anything, the class is not required to have a resource to be moved and a 'move constructor' may not be able to move a resource as in the allowable (but maybe not sensible) case where the parameter is a const rvalue reference (const T&&).
Nor is there any guarantee doing so would actually be advantageous, depending on implementation-details. The std::string constructor that takes a character pointer, requires a NUL-terminated string. So it is multiple characters.
std::string
will make a copy of the null terminated string argument and manage that copy. There's no way to have it take ownership of a string you pass to it. So what you're doing is correct, the only improvement I'd suggest is a check for nullptr
, assuming that is a valid return value for f()
. This is necessary because the std::string
constructor taking a char const *
requires that the argument point to a valid array, and not be nullptr
.
char* cstring = f();
std::string s(cstring ? cstring : "");
delete[] cstring; // You most likely want delete[] and not delete
Now, if you don't need all of std::string
's interface, or if avoiding the copy is important, then you can use a unique_ptr
to manage the string instead.
std::unique_ptr<char[]> s{f()}; // will call delete[] automatically
You can get access to the managed char *
via s.get()
and the string will be delete
d when s
goes out of scope.
Even if you go with the first option, I'd suggest storing the return value of f()
in a unique_ptr
before passing it to the std::string
constructor. That way if the construction throws, the returned string will still be deleted.
There is no standard way for a std::string
to take ownership of a buffer you pass.
Nor to take responsibility of cleaning up such a buffer.
In theory, an implementation, knowing all the internal details, could add a way for a std::string
to take over buffers allocated with their allocator, but I don't know of any implementation which does.
Nor is there any guarantee doing so would actually be advantageous, depending on implementation-details.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With