Although c_str() returns a null terminated version of the std::string, surprises may await when mixing C++ std::string with C char* strings.
Null characters may end up within a C++ std::string, which can lead to subtle bugs as C functions will see a shorter string.
Buggy code may overwrite the null terminator. This results in undefined behaviour. C functions would then read beyond the string buffer, potentially causing a crash.
#include <string>
#include <iostream>
#include <cstdio>
#include <cstring>
int main()
{
std::string embedded_null = "hello\n";
embedded_null += '\0';
embedded_null += "world\n";
// C string functions finish early at embedded \0
std::cout << "C++ size: " << embedded_null.size()
<< " value: " << embedded_null;
printf("C strlen: %d value: %s\n",
strlen(embedded_null.c_str()),
embedded_null.c_str());
std::string missing_terminator(3, 'n');
missing_terminator[3] = 'a'; // BUG: Undefined behaviour
// C string functions read beyond buffer and may crash
std::cout << "C++ size: " << missing_terminator.size()
<< " value: " << missing_terminator << '\n';
printf("C strlen: %d value: %s\n",
strlen(missing_terminator.c_str()),
missing_terminator.c_str());
}
Output:
$ c++ example.cpp
$ ./a.out
C++ size: 13 value: hello
world
C strlen: 6 value: hello
C++ size: 3 value: nnn
C strlen: 6 value: nnna�