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�