2

标准中是否对以下行为有任何解释?

以下代码:

#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 并且两者的行为方式相同,我已经尝试了该示例。

谢谢你的帮助!

4

3 回答 3

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!

现在它给出了正确的输出(这是您的代码- 幸运的是,即使 coliru 也给出了与您在机器上观察到的相同的输出。请注意,虽然不能保证此输出,但正是因为代码调用了 UB。)。

于 2013-10-20T13:24:53.167 回答
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;
于 2013-10-20T13:29:34.610 回答
0

这个问题的答案在这里: stringstream, string, and char* conversion chaos

stringstream.str() 返回一个临时字符串对象,该对象在完整表达式的末尾被销毁。如果您从该 (stringstream.str().c_str()) 获得指向 C 字符串的指针,它将指向在语句结束处被删除的字符串。

于 2013-10-20T13:30:25.483 回答