5

I have a code like this

int main()
{
    std::stringstream oss;
    std::cerr.rdbuf( oss.rdbuf() );

    std::cerr << "this goes to cerr";
    std::cout << "[" << oss.str() << "]";
}

But i get the output of the program as

[this goes to cerr]Segmentation fault

How does the program segfault?

cpx
  • 16,251
  • 19
  • 83
  • 139
Prasanth Madhavan
  • 11,759
  • 15
  • 60
  • 93

2 Answers2

12

This is because you do not restore the buffer of cerr before your program exits. Do it like this:

#include <iostream>
#include <sstream>

int main()
{
  std::stringstream oss;
  std::streambuf* old = std::cerr.rdbuf( oss.rdbuf() );

  std::cerr << "this goes to cerr";
  std::cout << "[" << oss.str() << "]";
  std::cerr.rdbuf(old);
}

See this answer of mine for a solution that is exception safe.

Community
  • 1
  • 1
Björn Pollex
  • 72,744
  • 28
  • 189
  • 274
2

The other answer correctly address the how does this program segfault part of your question. However, I feel that the real question Redirecting stderr to stdout using string stream.. deserves a better answer:

You may simplify the whole shebang and make it scale and perform a infitely better better by just aliasing cerr to cout:

#include <iostream>

int main()
{
    std::cerr.rdbuf(std::cout.rdbuf());
    std::cerr << "this goes to cerr";
}

If you really want to be explicit:

    std::cerr.copyfmt(std::cout);
    std::cerr.clear(std::cout.rdstate());
    std::cerr.rdbuf(std::cout.rdbuf());

You can verify that the text is actually received on stdout when run

sehe
  • 350,152
  • 45
  • 431
  • 590