
Dirk Griffioen wrote:
Hi,
I would love to use the boost::iostreams lib, so I created a filter (which, in this case, does encryption)
but instead of passing it std::cout I would like to pass it some other stream, a stringstream for instance (or any kind of ostream/istream, depending on the direction).
However, I was very surprised to find the following code taking 100% cpu and not returning. It probably means I did something wrong, but I can't seem to find it.
I found the problem, and fortunately it is not an iostreams bug. But the fact that the source of trouble was not obvious to me makes it clear that many others will run into the same problem, so it needs to be stressed somewhere in the documentation, maybe in several places. The problem is that the stringstream is being freed while it is still owned by the filtering_stream, which attempts to flush the stringstream in its destructor. Most filters and devices are stored as copies, or are reference-counted, so usually there is no problem. streams and stream buffers are stored by reference, however, and so must outlive the containing filtering_stream. (More precisely, a stream or stream buffer must outlive the filtering_stream or be removed from the filtering_stream's internal chain before it is destroyed.) Jonathan Turkanis wrote:
#include <iostream> #include <sstream> #include <boost/iostreams/filtering_stream.hpp>
int main() { boost::iostreams::filtering_ostream out; std::ostringstream os;
Note: os is destroyed before out!!!
out.push(os); out << "test" << std::endl; //out << "test" << "\n"; std::cout << os.str(); }
If the first two declarations are interchanged, everything is peachy. The reason it worked with cout is that cout is guaranteed to be available until the end of the program. Jonathan