标准中是否有以下行为的解释?
以下代码:
#include <sstream>
#include <iostream>
using namespace std;
int main()
{
ostringstream os1;
ostringstream os2;
os1 << 1 << " " << 2;
os2 << 1 << " " << 2 << " " << 3;
const char *p = os1.str().c_str();
cout << os2.str() << endl;
cout << p << endl;
return 0;
}
显示输出:
1 2 3
1 2 3
但是,我希望它能显示出来:
1 2 3
1 2
看起来os1对象在某种程度上受到os2的影响,如果我删除os2.str()调用,示例行为正确。
如果Solaris Studio 12.2和G ++ 4.8.1都以相同的方式运行,我尝试过该示例。
感谢您的帮助!
答案 0 :(得分:4)
const char *p = os1.str().c_str();
以上是问题所在。
os1.str()
通过复制内部字符串缓冲区返回临时字符串对象。而你正在使用.c_str()
临时对象,它会在完整表达式结束时被销毁。结果是,当您使用p
进行打印时,std::cout
指向被销毁的对象。
也就是说,您的程序调用未定义的行为(UB)。
试试这个:
auto s = os1.str();
const char *p = s.c_str(); //s is not a temporary object anymore!
现在它提供correct output(这是your code - 幸运的是,即使coliru也提供了与您在计算机上观察到的相同的输出。请注意,此输出不尽管保证正是因为代码调用了UB。)。
答案 1 :(得分:2)
我认为问题与保留c_str()
返回的指针有关。
ostringstream::str()
正在返回一个临时字符串对象,并且您正在保存指向其内部char
数组的指针。但是一旦该行执行,返回的字符串对象将被删除。所以你的指针无效。
如果由于某种原因想要保留c_str指针,则还需要保留字符串的副本:
string s = os1.str();
const char *p = s.c_str();
cout << os2.str() << endl;
cout << p << endl;
答案 2 :(得分:0)
这个问题的答案在这里: stringstream, string, and char* conversion confusion
stringstream.str()返回一个临时字符串对象,该对象在完整表达式的末尾被销毁。如果你从那里得到一个指向C字符串的指针(stringstream.str()。c_str()),它将指向一个字符串,该字符串在语句结束时被删除。