Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it legal to write to std::string?

In std::string there are only const members to fetch the data like c_str(). However I can get a reference to the first element of the string via operator[] and I can write to it.

For example, if I have function:

void toupper(char *first,char *last_plus_one);

I can write directly to vector getting a pointer to the first element:

vector<char> message // has "Some Message";
toupper(&message[0],&message[0]+message.size());

Can I do same thing with std::string?

string message="Some Message";
toupper(&message[0],&message[0]+message.size());

Does the standard guarantee that the location of the memory is actually linear? ie:

&(*(message.begin()+n)) == &message[n]

Thanks.

like image 556
Artyom Avatar asked Apr 17 '09 15:04

Artyom


People also ask

Should I use std::string?

Should I stick to std::string in every case? Yes, it is quite versatile and you have the whole algorithm set to help you. If you use a char you may have to write the same method which already exists.

Can you use std::string in C?

The std::string class manages the underlying storage for you, storing your strings in a contiguous manner. You can get access to this underlying buffer using the c_str() member function, which will return a pointer to null-terminated char array. This allows std::string to interoperate with C-string APIs.

Is std::string the same as string?

There is no functionality difference between string and std::string because they're the same type.

Is std::string reference counted?

So, yes it is ref counted. Also, from the discussion here: Yes, std::string will be made non-reference counting at some point, but as a non-reference-counted string is valid in C++98 as well, one option would be to switch to a non-ref-counted string for both -std=c++98 and -std=c++11 modes.


4 Answers

Herb Sutter has this to say (http://herbsutter.wordpress.com/2008/04/07/cringe-not-vectors-are-guaranteed-to-be-contiguous/#comment-483):

current ISO C++ does require &str[0] to cough up a pointer to contiguous string data (but not necessarily null-terminated!), so there wasn’t much leeway for implementers to have non-contiguous strings, anyway. For C++0x we have already adopted the guarantee that std::string contents must indeed be stored contiguously. For details, see http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#530

And Matt Austern says similar in the referenced document (http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#530).

So, it seems that you can assume that once you call str[0] you do get a modifyable array of characters (but note that it is not required to be null terminated).

like image 169
Michael Burr Avatar answered Oct 16 '22 14:10

Michael Burr


std::string will be required to have contiguous storage with the new c++0x standard. Currently that is undefined behavior.

like image 31
CTT Avatar answered Oct 16 '22 14:10

CTT


Yes you can modify a string.

You can also use it in algorithms that use iterators.

You can not use it in the same way as a vector<> because there is no guarantee that elements are in contiguous memory locations (yet: coming to a standard near you soon).

So if you modify your approach to use iterators rather than pointers it should work. And because iterators behave very much like pointers the code changes should be negligible.

template<typename I>
void toupper(I first,I last_plus_one)
{
    // Probably the same code as you had before.
}


{
     std::string  s("A long string With Camel Case");

     toupper(s.begin(),s.end());
}
like image 21
Martin York Avatar answered Oct 16 '22 16:10

Martin York


As it has been pointed-out, one can use strings in algorithms that use iterators; the same case can be implemented using std::transform Ex:- consider a string 's' to be converted to lower case:

int (*pf)(int)=tolower; //lowercase
std::transform(s.begin(), s.end(), s.begin(), pf); 

Regards,

like image 29
Abhay Avatar answered Oct 16 '22 16:10

Abhay