Boost logo

Boost :

From: Sean Huang (huangsean_at_[hidden])
Date: 2006-02-18 14:12:16


> Since I don't normally test with msvc8 it's alot of work for me to setup
> an
> environment to see if making the chang would be effective -- I didn't see
> anything on the MS site that made it clear that moving to
> basic_ostringstream
> would actually resolve the problem. However, if you want to try out some
> replacements and verify that using ostringstream will work, I'm willing to
> test and put in the changes. So specifically if you replace
> std::basic_stringstream with std::basic_ostringstream in
> date_time/time_facet.hpp that should be a reasonable test to see if there
> is
> an effect. I've attached a changed version of the file which compiles and
> runs on Linux. Let me know.
>
> Jeff
>
Jeff,

Thanks! I've tried the new version and the memory leak stopped (using the
program posted by OP). I also did a search in data_time and found there are
other places where basic_stringstream could be replaced with
basic_ostringstream. I understand this is a lot of hassles for you so we
decided we would apply the changes ourselves (is there anyway we could push
Microsoft to release a patch?).

As for the bug, I'll try to explain a bit more below.

If you have a copy of VC8, you can take a look at <ostream> and <istream>.
Both basic_ostream and basic_istream derive from basic_ios and
basic_iostream derives from basic_ostream and basic_istream. The
basic_iostream constructor used by basic_stringstream is coded as:

explicit __CLR_OR_THIS_CALL basic_iostream(basic_streambuf<_Elem, _Traits>
*_Strbuf)

: basic_istream<_Elem, _Traits>(_Strbuf, false),

basic_ostream<_Elem, _Traits>(_Strbuf)

{ // construct from stream buffer pointer

}

basic_ios::init is called from the constructors of both basic_istream and
basic_ostream in this case. basic_ios::init in turn calls ios_base::Init
where a std::locale* member _Ploc (a raw pointer) is newed. This is where
the memory leak occurs.

If you look at Mr. Plauger's patch, he changed one of the basic_iostream
constructors from the above to:

explicit __CLR_OR_THIS_CALL basic_iostream(basic_streambuf<_Elem,_Traits>
*_Strbuf)
: basic_istream<_Elem, _Traits>(_Strbuf, false),
basic_ostream<_Elem, _Traits>(_Noinit, false)
{ // construct from stream buffer pointer
}

basic_ios::init is not called in this constructor of basic_ostream so _Ploc
is only newed once.

HTH,

Sean


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