This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Re: strstream.h (deprecated) is broken
- From: Paolo Carlini <pcarlini at unitus dot it>
- To: Joe Buck <Joe dot Buck at synopsys dot com>
- Cc: Michael Veksler <VEKSLER at il dot ibm dot com>, gcc at gcc dot gnu dot org
- Date: Sat, 01 Jun 2002 00:07:34 +0200
- Subject: Re: strstream.h (deprecated) is broken
- References: <200205312108.OAA13443@atrus.synopsys.com>
Joe Buck wrote:
>>>gcc version 3.2 20020530 (experimental)
>>>
>>>$ g++ -Wno-deprecated t.cpp
>>>$ ./a.out
>>>Segmentation fault (core dumped)
>>>$ cat t.cpp
>>>#include <strstream.h>
>>>#include <iostream>
>>>
>>>int main()
>>>{
>>> strstream s;
>>> for (unsigned i=0 ; i!= 8 ; ++i)
>>> s << i << std::endl;
>>> s << std::ends;
>>>
>>> return 0;
>>>}
>>>
>>>
>
>By the way, I can't duplicate the crash with 20020529 on Solaris.
>What platform did you use?
>
Hi.
I could reproduce the problem on i686-pc-linux-gnu.
I'm currently testing the following simple patch, which seems to work
well for me (the testcase runs ok indeed):
*** strstream.cc.~1.9.~ Wed May 15 15:15:17 2002
--- strstream.cc Fri May 31 23:34:00 2002
*************** strstreambuf::strstreambuf(const unsigne
*** 139,151 ****
strstreambuf::~strstreambuf()
{
if (_M_dynamic && !_M_frozen)
- {
- char* p = this->eback();
- _M_free(p);
- if (p == _M_buf)
- _M_buf = 0;
- }
- if (_M_buf)
_M_free(_M_buf);
}
--- 139,144 ----
The rationale is the following:
1- For strstream the allocated buffer must be freed only when _M_dynamic
&& !_M_frozen, not otherwise.
2- The beginning of the low level buffer is given, in general, that is
at any time, by _M_buf, *not* by eback(), which may be != _M_buf if
there are chars in the putback area.
3- Therefore a single _M_free(_M_buf) - i.e., the dual of the _M_buf =
_M_alloc(_M_buf_size); performed at construction time - should be ok.
4- Note1: it is not necessary to explicitly make sure that _M_buf !=
NULL since the implementation of _M_free does this for us.
5- Note2: 2 + 3 would explain pretty well why we are currently crashing:
when the putback area is non-empty eback() != _M_buf, therefore
additionally to _M_free(p) we carry out also _M_free(_M_buf) thus
freeing part of the memory two times.
Could you please test/comment on the simple patch above?
Ciao,
Paolo.