strdup with stringstreams causes valgrind errors
c++, valgrind
Solution
const char *s = str.str().c_str();
The str() returns a string object. You get a pointer to some internal data of it using c_str, then at the end of the line the string object is deleted. But you still have a pointer to the deleted internal string.
You need to do it like this -
std::string s = str.str();
const char* s = s.c_str()
to ensure that the string isn't deleted.
Problem
I have the following problem: I am writing a C++ program that has to wrap around a C library, so when I interact with the library I always have to use `char*` instead of `std::string` for all operations. In order to avoid working with `char*` as much as possible, I do the formatting with stringstreams, for example like this: ``` #include <iostream> #include <sstream> #include <string.h> #include <cstdlib> using namespace std; int main(int argc, char** argv) { ostringstream str; str << argv[0] << "+" << "hello"; const char *s = str.str().c_str(); char *y = strdup(s); // this I would give to a library function cout << y << endl; free(y); return 0; } ``` As far as the output goes, the program correctly outputs "./test+hello". However, valgrind gives me a lot of errors of the type ``` ==30350== Invalid read of size 1 ==30350== at 0x402B858: __GI_strlen (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so) ==30350== by 0x4213475: strdup (in /usr/lib/libc-2.16.so) ==30350== by 0x41B2604: (below main) (in /usr/lib/libc-2.16.so) ==30350== Address 0x4341274 is 12 bytes inside a block of size 25 free'd ==30350== at 0x4029F8C: operator delete(void*) (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so) ==30350== by 0x410387A: std::string::_Rep::_M_destroy(std::allocator<char> const&) (in /usr/lib/libstdc++.so.6.0.17) ==30350== by 0x41B2604: (below main) (in /usr/lib/libc-2.16.so) ``` What am I doing wrong?