问题
Something a lot of C++ programmers miss (read: me) when first using stringstream
s is the fact that the copy returned by stringstream::str()
is a temporary, which lasts until the end of the expression it's used in. However, I don't understand:
- How this is done. Looking in the
sstream
header for libstdc++, I only see a copy being made and returned. How is the lifetime restricted? - Why this is the desired behavior, especially since it is such a common gotcha. If a copy is being made anyway, why can't I take ownership of it?
Note that this is not a duplicate of stringstream, string, and char* conversion confusion. That goes over explaining the behavior and workarounds; I'm looking for mechanics and rationale.
回答1:
This is not a problem of stringstream
. It is the problem of c_str
function - it returns pointer to a char*
representation of std::string
, but it lives only during lifetime of an original string. When you call char *str = ss.str().c_str()
the following actually happens:
string tmp = ss.str();
char *str = tmp.c_str();
tmp.~string (); // after that line the pointer `str` is no longer valid
c_str
is a dangerous function provided only for compatibility and speed purposes and you should avoid using it.
回答2:
stringstream::str()
returns a string
. Period. It does so by value, so you can do whatever you want with it (e.g. certainly take ownership).
回答3:
How this is done? Looking in the sstream header for libstdc++, I only see a copy being made and returned. How is the lifetime restricted?
str()
returns by value, meaning the object it returns is destroyed by the end of the full expression. It's simply the way temporaries work.
Why this is the desired behavior, especially since it is such a common gotcha. If a copy is being made anyway, why can't I take ownership of it?
It's an amendment from the traditional IOStreams. The old deprecated class of streams strstream
had an str()
method that returned a pointer to its internal buffer. To protect against invalidation of the pointer, the stream had to be "frozen", meaning the buffer could not be resized.
The Standard IOStreams returns a copy of the buffer as a std::basic_string<charT>
object so that freezing the stream is no longer necessary.
来源:https://stackoverflow.com/questions/21534682/stringstreamstr-copy-lifetime