1

Is a std::string without a null-character in the end valid and can it be acquired like this?:

std::string str = "Hello World";
str.resize(str.size() - 1);

For those who are curious:

I have a 3rd party function taking a string and iterating over the chars (using iterators). Unfortunately the function is buggy (as its a dev-version) and cannot deal with null-characters. I dont have another signature to chose from, I cant modify the function (as I said, 3rd party and we dont want to fork) and at the same time I dont want to reinvent the wheel. As far as I can tell, the function should work as desired without the null-character so I want atleast to give it a try.

The iteration takes place like this:

bool nextChar(CharIntType& c)
{
    if (_it == _end) return false;
    c = *_it;
    ++_it;
    return true;
}

where _it is initialized to std::string::begin() and _end to std::string::end()

9
  • 1
    I'd suppose that the second line will remove the 'd' character. Commented Jan 20, 2014 at 21:51
  • By end, do you mean str[str.size()]? Or str.back()? Commented Jan 20, 2014 at 21:52
  • 1
    As of C++11, there should always be a hidden null character at the end. Nothing you'd run into with an iterator, though, and not part of the string as far as the user of the class is concerned. Also, pop_back will do what this code does. Commented Jan 20, 2014 at 21:54
  • @BenjaminLindley The current std::string would hold Hello World\0, I simply dont want that \0 in the end. Commented Jan 20, 2014 at 21:55
  • I will update the question acordingly to show the iteration part Commented Jan 20, 2014 at 21:55

3 Answers 3

7

Until C++11, std::string was not required to include a trailing nul until you called c_str().

http://en.cppreference.com/w/cpp/string/basic_string/data

std::string::data()

Returns pointer to the underlying array serving as character storage. The pointer is such that the range [data(); data() + size()) is valid and the values in it correspond to the values stored in the string.

The returned array is not required to be null-terminated. If empty() returns true, the pointer is a non-null pointer that should not be dereferenced. (until c++11)

The returned array is null-terminated, that is, data() and c_str() perform the same function. If empty() returns true, the pointer points to a single null character. (since c++11)

From this we can confirm that std::string::size does not include any nul terminator, and that std::string::begin() and std::string::end() describe the ranges you are actually looking for.

We can also determine this by the simple fact that std::string::back() doesn't return a nul character.

#include <iostream>
#include <string>

int main() {
    std::string s("hello, world");
    std::cout << "s.front = " << s.front() << " s.back = " << s.back() << '\n';
    return 0;
}

http://ideone.com/nUX0AB

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

2 Comments

It looks like somewhere, somewhen an extra null-char found its way into my string (the string undergoes alot of code, its sent atleast twice times over the wire), while pop_back() helped in this case, your answere is formally correct and answeres the original question, and more importantly the reaction I got on SO here (including your answere) helped me to find and fix the actual problem. Thus I accepted your answere.
Ah - yeah - you can of course write '\0's into the underlying char array, and if you construct it with a string and pass it len + 1 it will copy the '\0' into the string. Always found it a little annoying that std::string has both length and size and they are both the same value.
0

While it is possible to have non null terminated strings I would not recommend it, strings are null terminated for a good reason, i would actually recommend in this instance that you either go ahead and write the function properly or get in touch with the third party and have them fix it.

To answer your questions yes a std::string is valid if it is not null terminated, to achieve this you can use the overload of string copy with a maximum length loaded, once again i do not recommend this.

See this page for more information: http://c2.com/cgi/wiki?NonNullTerminatedString

Comments

-1

This is a very late answer but I just post it so that anyone who comes later can use it for their reference. If you write a null terminated string into the string.data() array, it will terminate the string and would not let you to continue concatenate the string if you need to. The way to solve it is already answer in the question.

  str.resize(str.size() - 1); 

This would solve the problem, I have tested out in my code.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.