Reputation: 767
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.
Upvotes: 2
Views: 165
Reputation: 726479
The problem is that the pointer returned by c_str()
remains valid only for as long as the string from which it is obtained is not modified or disposed.
When you do this
const char* str2 = get_file_contents("test.txt").c_str();
the string returned by get_file_contents("test.txt")
is temporary. The call to c_str()
returns a pointer to its internal content, but then the string gets destroyed, making the return invalid.
Upvotes: 2
Reputation: 129
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
...
Upvotes: 4
Reputation: 48605
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.
Upvotes: 3