In many code samples, people usually use '\0'
after creating a new char array like this:
string s = "JustAString";
char* array = new char[s.size() + 1];
strncpy(array, s.c_str(), s.size());
array[s.size()] = '\0';
Why should we use '\0'
here?
The title of your question references C strings. C++ std::string
objects are handled differently than standard C strings. \0
is important when using C strings, and when I use the term string in this answer, I'm referring to standard C strings.
\0
acts as a string terminator in C. It is known as the null character, or NUL, and standard C strings are null-terminated. This terminator signals code that processes strings - standard libraries but also your own code - where the end of a string is. A good example is strlen
which returns the length of a string: strlen
works using the assumption that it operates on strings that are terminated using \0
.
When you declare a constant string with:
const char *str = "JustAString";
then the \0
is appended automatically for you. In other cases, where you'll be managing a non-constant string as with your array example, you'll sometimes need to deal with it yourself. The docs for strncpy, which is used in your example, are a good illustration: strncpy
copies over the null terminator character except in the case where the specified length is reached before the entire string is copied. Hence you'll often see strncpy
combined with the possibly redundant assignment of a null terminator. strlcpy
and strcpy_s
were designed to address the potential problems that arise from neglecting to handle this case.
In your particular example, array[s.size()] = '\0';
is one such redundancy: since array
is of size s.size() + 1
, and strncpy
is copying s.size()
characters, the function will append the \0
.
The documentation for standard C string utilities will indicate when you'll need to be careful to include such a null terminator. But read the documentation carefully: as with strncpy
the details are easily overlooked, leading to potential buffer overflows.