I have a function that reads a file and returns a string.
string get_file_contents(const char *filename)
{
ifstream in(filename);
if (in)
{
ostringstream contents;
contents << in.rdbuf();
in.close();
return(contents.str());
}
throw(errno);
}
I read a file containing only success and convert the return value it into a c style string in two different ways with different results.
string str = get_file_contents("test.txt");
const char* str1 = str.c_str();
cout << "printing str1: ";
cout << str1 << endl;
const char* str2 = get_file_contents("test.txt").c_str();
cout << "printing str2: ";
cout << str2 << endl;
output:
printing str1: success
printing str2:
I don't understand why str2 is empty. Any insight is appreciated.
Your function call returns a string which is temporary in both cases. Calling c_str() on that temporary returns a pointer that may be dangling after the statement completes. Using the string to store the result is correct, which is why the first call works. The second call may have undesirable effects due to the dangling pointer.
Since str2 is a pointer, it's not simply empty, it's pointing to a non-existent string. This could be a danger.
Storing the result into another string, as in the first call, might be optimized well by the compiler.
You may be able to shorten that file read as well:
...
ifstream in(filename);
if (in)
{
return string(istreambuf_iterator<char>(in), istreambuf_iterator<char>());
}
// throw exception
...
With str1 you are setting it to the internals of a local variable str which remains valid until it goes out of scope at the end of the function (as long as you don't modify str).
With str2 you point it at the internals of a temporary string that is never assigned to a local variable and so it gets destroyed immediately after you assigned it.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With