C++ basic_ostringstream::str悬挂指针

C++ basic_ostringstream::str悬挂指针,c++,c++11,C++,C++11,最近,我在以下代码中发现了错误: ostringstream o; o << "some string"; const char* s = o.str().c_str(); // empty string instead of expected "some string" ostringstreamo; o否,消息是一个std::字符串,因此您可以在该点复制char缓冲区的内容 临时值在调用它的函数的范围内持续,在本例中为构造函数 这个临时表达式一直持续到抛出表达式的末尾(因此它包

最近,我在以下代码中发现了错误:

ostringstream o;
o << "some string";
const char* s = o.str().c_str(); // empty string instead of expected "some string"
ostringstreamo;
o否,消息是一个std::字符串,因此您可以在该点复制char缓冲区的内容


临时值在调用它的函数的范围内持续,在本例中为构造函数

这个临时表达式一直持续到抛出表达式的末尾(因此它包括
my_exception
构造函数)。如果将my_异常更改为存储const char*,您将回到原来的问题。一个更好的解决方案是给我的_异常一个构造函数,它接受一个
const std::string&
或者甚至一个
const ostringstream&
,并直接从中构造消息。将std::string转换为char*,然后立即将其更改回去,这特别困难。@Jarod42:您能给我一些确认吗(可能是从C++规范)的“临时持续到抛出表达式结束”?这是我最重要的一点。谢谢。@ 0123456789:正如你所说的“在表达式末尾将被破坏”,它被用于<代码>抛出MyExExt(o Stand)(cScript())。
一个抛出表达式。这不会改变您案例中的行为(在构造函数中就足够了)。当您使用它时,您仍然可以重构代码。如果您只是从
std::runtime\u error
派生(而不是重新实现其功能),您可以简单地向它传递一个
std::string
,删除一堆代码,甚至可以避免一个副本。
ostringstream o;
o << "error description";
throw my_exception(o.str().c_str());

...

my_exception::my_exception(const char* s) :
    message(s)     // message is std::string
{}