Ben Thomas wrote:
[color=blue]
> Thankx for the answer![/color]
Please don't top-post. Re-read section 5 of the FAQ for posting guidelines.
http://www.parashift.com/c++-faq-lite/
[color=blue]
>
> 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,[/color]
This proves absolutely nothing.
[color=blue]
> so scope seems to be okay,[/color]
Bad conclusion.
[color=blue]
> only that it's empty in one call and not in
> the other.[/color]
It's undefined in one call, and not in the other.
[color=blue]
> 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();[/color]
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.
[color=blue]
>
> and this
>
> func( stream.str().c_str() ); // void func( const char* s );[/color]
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.
[color=blue]
>
> I just can't make sense of it... maybe the problem is elsewhere after all.[/color]
I'm quite sure this IS the problem. I've verified my assumption about
the return type of std::ostringstream::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
--
My email address is valid, but changes periodically.
To contact me please use the address from a recent posting.