It is guaranteed to work on a vector since the elements of a vector are stored contiguously.Which, annoyingly, is not guaranteed to work, but it does in practice.
It is guaranteed to work on a vector since the elements of a vector are stored contiguously.Which, annoyingly, is not guaranteed to work, but it does in practice.
Look up a C++ Reference and learn How To Ask Questions The Smart WayOriginally Posted by Bjarne Stroustrup (2000-10-14)
It was corrected in the 2003 revision to the C++ standard, as CornedBee pointed out.I was under the impression that this was not actually guaranteed, but always true in practice, and that the oversight would be corrected in C++0x. Am I wrong?
Look up a C++ Reference and learn How To Ask Questions The Smart WayOriginally Posted by Bjarne Stroustrup (2000-10-14)
>> I was under the impression that this was not actually guaranteed, but always true in practice, and that the oversight would be corrected in C++0x.
I've seen this written about string.
Yes, C++0x will contain the same guarantee for std::string, if I remember correctly. I know for sure that the proposal exists; I'm not 100% sure that it was accepted.
All the buzzt!
CornedBee
"There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
- Flon's Law
However, if you use this technique and let outside code modify the storage directly, how can the container guarantee that it won't get into an invalid state?
I might be wrong.
Quoted more than 1000 times (I hope).Thank you, anon. You sure know how to recognize different types of trees from quite a long way away.
Because the container (vector or string in this case) has no state that references the values in the array it holds. When modifying the internal data, you can't change the size of the array or make it point somewhere else, you can only change the values in that array. Since vector/string doesn't care about what is inside the array, the state won't be invalidated. Note that by allowing the user to modify the internal array you are effectively requiring that an implementation not care about the contents of the array.
A string implementation that uses copy-on-write does care about the internals of the array, since a change to the values means that you might have to create a new copy. This might be one reason why string doesn't provide non-const access to its internal storage, since COW strings could not be implemented. My guess is that these are now out of favor which might be why they are considering making string like vector in C++0x.
So, if I want to strcpy to such vector, I'd need to make sure first that the vector is large enough and resize it accordingly? So it wouldn't be as safe as a std::string but just more convenient than a char array since the resizing is implemented for me?
I might be wrong.
Quoted more than 1000 times (I hope).Thank you, anon. You sure know how to recognize different types of trees from quite a long way away.
COW strings are possible, you'd just have to copy the moment someone obtains the pointer. But this problem exists already, because the [] operator on non-const strings must return a true reference. Because modifications through such a reference can't be tracked either, a COW string must treat every [] operator call as a write.
That's one of the two big reasons COW strings are disappearing quickly. The other is that the multi-threading issues are huge. Most COW implementations, when made thread-safe, are actually slower than naive implementations due to all the synchronization.
The order of the day is the small buffer optimization, SBO.
Yes, if you want to strcpy with a vector as the target, you have to make sure it's large enough. Just like you'd have to ensure it with a normal array or block of memory returned from new/malloc. The main reason to use it is that it follows the RAII pattern - it's pretty much equivalent to a boost::scoped_array, really, except that it is more convenient because, as you say, it handles resizing for you.
But yes, all C string operations require you to ensure in advance that the buffers are large enough. That's why they're to be avoided and only used when interfacing with legacy C libraries.
All the buzzt!
CornedBee
"There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
- Flon's Law