1

C++11 guarantees that std::string stores the nul terminator internally. How can that be achieved without an explicit terminate method?

Example:

std::string foo("Baz");
printf("foo contains %s\n",&foo[0]); //Completely safe
erip
  • 16,374
  • 11
  • 66
  • 121
user877329
  • 6,717
  • 8
  • 46
  • 88
  • 2
    Not sure I understand the question. Could you explain what you mean? For instance, why would a `terminate` method be necessary? – erip May 05 '16 at 17:36
  • By internally having a pointer to an array of at least `size() + 1` characters with a terminator as the last character, probably. – Some programmer dude May 05 '16 at 17:40
  • The string constructor copies the string and adds a null terminator. – Daniel May 05 '16 at 17:42
  • @JoachimPileborg Yes, but what happens when I append to chars to that string. Then it is no longer zero-terminated (unless we write one extra byte). Also it fails if we just truncates the string without clearing memory. – user877329 May 05 '16 at 17:42
  • 3
    Truncating is easy, just set the terminator at the new size. Appending, either reallocate like `std::vector`, or allocate some extra memory to begin with and just copy the new character over the terminator and set the terminator at the next character. – Some programmer dude May 05 '16 at 17:46
  • Oh and I really recommend you to implement your own string class, just for the learning experience. Try making it with the same interface as [`std::string`](http://en.cppreference.com/w/cpp/string/basic_string). – Some programmer dude May 05 '16 at 17:48
  • @JoachimPileborg Or just to make sure GCC does not use its COW implementation :-( – user877329 May 05 '16 at 17:49
  • 2
    @user877329: COW is illegal in C++11. GCC eventually caught up with that. – Nicol Bolas May 05 '16 at 18:06

1 Answers1

4

The standard requires that the string you get from data() is NUL terminated, and requires that the references generated from operator[] are contiguous and NUL terminated. That's all the specification says about it.

It is the job of the implementation to do that. Typically, this happens by just storing a NUL terminator at the end of the string, making the actual buffer size one larger than it appears. If you add characters, it still stores a NUL terminator at the end of the newly-appended-to sequence of characters. If you remove characters, it moves the NUL terminator appropriately.

This is what encapsulated types can do. They can establish and maintain invariants.

Community
  • 1
  • 1
Nicol Bolas
  • 449,505
  • 63
  • 781
  • 982