Comment by kloop
1 year ago
std::string isn't null terminated (or at least it isn't guaranteed to be, I don't think it's forbidden for an implementation to do that).
That's why the c_str method exists, so you can get a pointer to a null terminated character array
> std::string isn't null terminated
It is as of C++11. The constness of c_str() threw a wrench into that as soon as C++ got a threading model.
std::string is guaranteed to be null terminated since c++11.
std::string::c_str returns the same address as &string[0]
> std::string::c_str returns the same address as &string[0]
Note that this by itself doesn't imply null-termination, though as you say strings are indeed null-terminated now.
Edit: This is not particularly obvious, but the reason this has nothing to do with allocation or the return value is that the implementation could still leave space for the null terminator, but avoid actually setting it to zero until c_str() is invoked. That would neither affect the returned pointer nor the constant-time guarantee.
Shouldn't c_str() be null terminated? Then if it must point to the actual backing store, then that must also be a valid null terminated C string as there's no other way to use them.
3 replies →
Why downvotes? Ignoring C++11 changes for a minute, c_str is absolutely able to cause a reallocation if it needs to, such that after it returns, its return value and the value of data() are the same. Ergo no, the GP statement alone doesn’t imply anything.
2 replies →
I think std::string is actually required to be null terminated now in the latest standards. But even before it was basically required as that was the only way to make c_str() constant time.
> But even before it was basically required as that was the only way to make c_str() constant time.
Note that c_str() could've inserted the terminator in constant time, as long as the string kept space reserved for that. So this wouldn't have violated constant-time-ness, and it's not an insane thing to do considering it would save some instructions elsewhere. But yeah, the flexibility wasn't all that useful even in the beginning, and became even more useless as soon as C++ incorporated threading, due to the constness of the function.