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
  • 17,009
  • 20
  • 87
  • 142
Prasanth Madhavan
  • 12,657
  • 15
  • 62
  • 94

2 Answers2

13

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
  • 75,346
  • 28
  • 201
  • 283
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
  • 374,641
  • 47
  • 450
  • 633