stringstream::str copy lifetime

我是研究僧i 提交于 2019-12-12 07:29:54

问题


Something a lot of C++ programmers miss (read: me) when first using stringstreams 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:

  1. 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?
  2. 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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!