138

Will the below string contain the null terminator '\0'?

std::string temp = "hello whats up";
2
  • 5
    Will std::string always be null-terminated in C++11?. Commented Aug 1, 2012 at 5:01
  • 3
    At it stands now, the accepted answer from @jahhaj conflicts with the answer from user529758, whose answer is arguably more up to date. While perusing, I skipped Jesse Good's comment, so this is here to emphasize its importance. Commented Jun 19, 2020 at 7:06

6 Answers 6

142

No, but if you say temp.c_str() a null terminator will be included in the return from this method.

It's also worth saying that you can include a null character in a string just like any other character.

string s("hello");
cout << s.size() << ' ';
s[1] = '\0';
cout << s.size() << '\n';

prints

5 5

and not 5 1 as you might expect if null characters had a special meaning for strings.

Sign up to request clarification or add additional context in comments.

6 Comments

If you call temp.c_str() the null character will be included. If you really need it in the string just add it like any other character. temp.push_back('\0'). Now temp.c_str() will include two null characters.
@dupdupdup, as some of the replies have mentioned, if you need a null-terminated string you should call a s.c_str() on the constructred object. It will return a pointer to character array that is guaranteed to have '\0' at the end.
@Rico, Jahhaj How to terminate the string then. For eg - I added few characters to my string as str[i]. Now I'm not able to print it using cout.
To add to your point : Since the operator << is overloaded so, cout <<s, will although will print the complete string char by char, but , if you take c_str() and put to operator << it will print till the null char. following program depits this point. {string s("SampleString "); cout << s.size() << "\t" << s<<endl; s[3] = '\0'; cout <<"\n\n After Null \n\n"<< s.size() << "\t" << s<<endl; cout << "\n\n Taking c_str \n\n" << s.size() << "\t" << s.c_str() << endl; }
Actually, as of C++11 std::string is guaranteed to be null terminated. Specifically, s[s.size()] will always be '\0'.
|
120

Not in C++03, and it's not even guaranteed before C++11 that in a C++ std::string is continuous in memory. Only C strings (char arrays which are intended for storing strings) had the null terminator.

In C++11 and later, mystring.c_str() is equivalent to mystring.data() is equivalent to &mystring[0], and mystring[mystring.size()] is guaranteed to be '\0'.

In C++17 and later, mystring.data() also provides an overload that returns a non-const pointer to the string's contents, while mystring.c_str() only provides a const-qualified pointer.

10 Comments

With C++11, strings are now guaranteed to be contiguous in memory.
@zneak thanks! Updated. But I doubt there are any at least reasonably C++11-compilant compilers... even GCC has broken support for it.
@H2CO3 : C++11 aside, this was addressed in DR 530 in 2005. The vast majority of standard library implementations have stored string data in contiguous memory for at least as long.
Thank you @ildjarn, I was looking for that exactly. Part of the rationale for the move was that no one on the committee knew of an STL implementation that did not use continuous memory.
With C++17, there is now a char * std::string::data() function (returns a modifiable / non-const pointer to the string's contents). See the C++ reference: en.cppreference.com/w/cpp/string/basic_string/data Related thread: stackoverflow.com/a/34179377/9909817
|
22

This depends on your definition of 'contain' here. In

std::string temp = "hello whats up";

there are few things to note:

  • temp.size() will return the number of characters from first h to last p (both inclusive)
  • But at the same time temp.c_str() or temp.data() will return with a null terminator
  • Or in other words int(temp[temp.size()]) will be zero

I know, I sound similar to some of the answers here but I want to point out that size of std::string in C++ is maintained separately and it is not like in C where you keep counting unless you find the first null terminator.

To add, the story would be a little different if your string literal contains embedded \0. In this case, the construction of std::string stops at first null character, as following:

std::string s1 = "ab\0\0cd";   // s1 contains "ab",       using string literal
std::string s2{"ab\0\0cd", 6}; // s2 contains "ab\0\0cd", using different ctr
std::string s3 = "ab\0\0cd"s;  // s3 contains "ab\0\0cd", using ""s operator

References:

4 Comments

What do you mean by "int(temp[temp.size()]) will be zero"? Since temp is a std::string, temp[temp.size()] can be undefined. (We can't do temp.at(temp.size()) - out of range).
@starriet temp[temp.size()] is defined since C++11. It's only assigning anything but a char{} to it that would make it undefined. Reading it is never undefined. at checks for pos >= size() but for operator[] the behavior is only undefined for pos > size().
@TedLyngmo Sorry for being late, thanks! You're right. One question: std::string's operator[] returns a reference to char() if pos==size()(as explained in cppreference.com), but is it guaranteed that the returned char() is indeed the last element of the underlying memory? Or is it just an immediately constructed value, regardless of the actual element residing in the underlying memory of the string?
@starriet Yes it's guaranteed to be the last (accessible) element in a contiguous chunk of memory. If temp = "a"; then &temp[0] + 1 == &temp[temp.size()]. I mentioned accessible because the capacity() may be larger than the size().
2

Yes if you call temp.c_str(), then it will return null-terminated c-string.

However, the actual data stored in the object temp may not be null-terminated, but it doesn't matter and shouldn't matter to the programmer, because when then programmer wants const char*, he would call c_str() on the object, which is guaranteed to return null-terminated string.

1 Comment

Nor will the null terminator (if it exists) be included in the return from temp.size().
1

With C++ strings you don't have to worry about that, and it's possibly dependent of the implementation.

Using temp.c_str() you get a C representation of the string, which will definitely contain the \0 char. Other than that, i don't really see how it would be useful on a C++ string

Comments

1

std::string internally keeps a count of the number of characters. Internally it works using this count. Like others have said, when you need the string for display or whatever reason, you can its c_str() method which will give you the string with the null terminator at the end.

1 Comment

Can you give some references for this statement," std::string internally keeps a count of the number of characters. Internally it works using this count"

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.