$ gcc -v Reading specs from /usr/lib/gcc/i386-redhat-linux/3.4.5/specs Configured with: ../configure --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --enable-shared --enable-threads=posix --disable-checking --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-java-awt=gtk --host=i386-redhat-linux Thread model: posix gcc version 3.4.5 20051201 (Red Hat 3.4.5-2) $ uname -a Linux localhost.localdomain 2.6.9-34.0.1.EL #1 Wed May 24 07:40:56 CDT 2006 i686 i686 i386 GNU/Linux I encounter this bug when using ostringstream with an external buffer. When an external buffer is given to pubsetbuf(), it is copied into the internal buffer (_M_string). (The code comments in sstream indicate that it thinks it's destroying the buffer, but it's not.) If the size of the external buffer is <= 115, everything is fine. Above that, the internal buffer allocates additional storage in 128 byte increments (227, 355, ...), which increases its capacity() beyond its size(). The second step of pubsetbuf() calls _M_sync() to set up the put/get pointers. However, setp() is then called with the external buffer pointer as the first argument (correct) and ((buffer pointer) + _M_string.capacity()) as the second (incorrect). This capacity() is greater than the size of the external buffer, so the end put pointer points well past the end of the external buffer. In the following example, a size of 116 is given to pubsetbuf(). However, the capacity of the internal buffer is 227. 227 'x' chars get written into the external buffer. #include <iostream> #include <sstream> using namespace std; int main() { ostringstream oss; char *buf = new char[256]; memset(buf, 0, sizeof(buf)); oss.rdbuf()->pubsetbuf(buf, 116); cout << "INTERAL BUFF SIZE " << oss.str().size() << " " << oss.str().capacity() << endl; for (int i=0; i<1000; i++) { oss << "x"; } oss.rdbuf()->pubsetbuf(0, 0); cout << "EXTNERAL BUFF SIZE " << strlen(buf) << endl; } Let me know if I can provide any other info... Nick
Fixed already for gcc4.0.0 with the below: time to update your compiler, the 3.4.x branch is old and not maintained anymore... 2004-10-06 Paolo Carlini <pcarlini@suse.de> * include/std/std_sstream.h (_M_sync): When the caller is setbuf, don't trust _M_string.capacity() to be the size of the buffer area, use _M_string.size() in this case. * testsuite/27_io/basic_stringbuf/setbuf/char/4.cc: New. * testsuite/27_io/basic_stringbuf/setbuf/wchar_t/4.cc: Likewise.
The other thing is that sizeof(buf) will get you sizeof(char*) which is most likely not what you wantted anyways.
Sorry. I did not know that 3.4 was no longer supported. I wondered if upgrading to gcc4 would fix it, but was trying to stay in sync with the rest of my group. But it sounds like upgrading is something we should all do. Thanks for the prompt response! Nick
i guess i'm supposed to verify/close this...