Ben said:
Please don't top-post. Re-read section 5 of the FAQ for posting guidelines.
http://www.parashift.com/c++-faq-lite/
Okay, I have fixed the problem with displaying the pointers value and change
#include<ostream> with #include<sstream> and return 0 in the main function
and it's the same behavior!
The solution of a temp variable works! I too first though that it was a
scope problem, that's why I displayed the pointer value. Yet, they are the
same,
This proves absolutely nothing.
so scope seems to be okay,
Bad conclusion.
only that it's empty in one call and not in
the other.
It's undefined in one call, and not in the other.
Also, I don't know if there's a difference in scope between the
two kind of call... I have tryed to write a class that reproduce the same
kind of behavior but wasn't able to do so... maybe it's in the many level of
template with STL, but how can you make your class act differently between
this
const char* s = stream.str().c_str();
OK, I'll try to explain again (but I suspect you need to look up
"temporaries" or "temporary objects" in your C++ book).
stream.str() returns by value. This means that the result is copied into
a "temporary object". Now, the ruled for temporary objects state that
they go out of scope at the end of the full expression in which they are
created. A full expression is an expression that is not a sub-expression
of any larger expression, therefore the full expression in this
particular case is the entire statement, minus the semi-colon. That
means that the temporary std::string object containing the result of
stream::str() is GONE once this statement completes. It no longer exists.
Since the pointer returned from std::string::c_str() ceases to be valid
when the std::string is modified or destroyed, your 's' pointer stops
being valid as soon as you initialize it.
and this
func( stream.str().c_str() ); // void func( const char* s );
In this case, the full expression includes the function call. The
function call uses the pointer while it's still valid. As soon as the
function completes, the temporary std::string object goes out of scope
and the pointer is no longer valid - but that's OK this time because you
haven't saved it anywhere.
I just can't make sense of it... maybe the problem is elsewhere after all.
I'm quite sure this IS the problem. I've verified my assumption about
the return type of std:
stringstream::str() by checking the standard.
What you are doing is roughly equivalent to this:
#include <iostream>
#include <cstring>
using namespace std;
class Stupid
{
char *str;
public:
Stupid() : str(new char[20]) { strcpy(str, "this is stupid");
cout << "Constructing a Stupid object" << endl; }
~Stupid() { delete [] str;
cout << "Destroying a Stupid object"
" (and releasing memory)" << endl; }
char *GetPtr() { return str; }
};
int main()
{
char *s = Stupid().GetPtr();
cout << "The string pointed to by s is:\n" << s << endl;
return 0;
}
If you can't see why this is horribly broken, try running it. The object
dies and releases its memory before you even have a chance to use 's'.
-Kevin