Boost logo

Boost :

From: Jonathan Turkanis (technews_at_[hidden])
Date: 2005-03-24 16:05:19


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


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk