This is the mail archive of the libstdc++@sourceware.cygnus.com mailing list for the libstdc++ project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Initialisation of a stringbuf


Hi Benjamin,

I ran across what looks like a bug in bits/std_sstream.h. The
following code illustrates the problem:

int main()
{
   string st("@silent");
   cerr << "size = " << st.size() << endl;
   cerr << "capacity = " << st.capacity() << endl;
   st.erase(0,1);
   cerr << "size = " << st.size() << endl;
   cerr << "capacity = " << st.capacity() << endl;

   istringstream is(st);
   cerr << "Before extraction, size within is = " <<
      is.str().size() << endl;
   cerr << "Before extraction, capacity within is = " <<
      is.str().capacity() << endl;
   string out;
   is >> out >> ws;
   cerr << "out is of size " << out.size() << endl;
   cerr << "out is of capacity " << out.capacity() << '\n' << endl;
}

It produces the output:

size = 7
capacity = 7
size = 6
capacity = 7
Before extraction, size within is = 6
Before extraction, capacity within is = 7
out is of size 7
out is of capacity 7

The string out has an extra character at the end that it shouldn't
have: my experiments showed that it was in fact a zero byte, 0x0.

The problem arises, it seems to me, in the initialisation of a
stringbuf, in the function _M_init_stringbuf(...), when _M_buf_size
is set to _M_string.capacity(). When, in the code above, I erase a
character at the beginning of the string, the size falls by one, as
it should, and the capacity stays as it was, also as it should. But,
when the function _M_really_sync(0,0) is called, the setg command in
that function sets _M_in_end to the end of the capacity of the
string, not to the end of the size, and thereby allows the zero byte,
which is just _S_terminal, to be available for extraction.

Here is the diff that I suggest:

*** std_sstream.h.bak	Thu Aug 19 01:19:59 1999
--- std_sstream.h	Wed Oct 13 22:40:46 1999
*************** namespace std {
*** 106,112 ****
  	// necessary as ostringstreams are implemented with the
  	// streambufs having control of the allocation and
  	// re-allocation of the internal string object, _M_string.
! 	_M_buf_size = _M_string.capacity();
  	_M_mode = __mode;
  	_M_really_sync(0, 0); 
        }
--- 106,112 ----
  	// necessary as ostringstreams are implemented with the
  	// streambufs having control of the allocation and
  	// re-allocation of the internal string object, _M_string.
! 	_M_buf_size = _M_string.size();
  	_M_mode = __mode;
  	_M_really_sync(0, 0); 
        }


When I remade the library after making this change, all the tests
done by "make check" still pass, and the problem of extracting the
string is solved. The last two lines of output from the program above
become, as they should:

out is of size 6
out is of capacity 6

Regards, Russell.

Russell Davidson                    email: russell@qed.econ.queensu.ca
Queen's University,
Kingston, Ontario, Canada           phone: 613-533-2264 
K7L 3N6                               Fax: 613-533-6668


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]