Opened 9 years ago

Closed 9 years ago

#3166 closed Bugs (fixed)

Possible Bug in Boost.Interprocess vectorstream

Reported by: chsalvia@… Owned by: Ion Gaztañaga
Milestone: Boost 1.40.0 Component: interprocess
Version: Boost 1.39.0 Severity: Problem
Keywords: Cc:


There is possibly a bug in the vectorstream class found in the Boost Interprocess library. It seems the internal pointer mp_high_water doesn't get updated every time new data is inserted into the stream via xsputn, which causes problems if you call seekp on a stream.

The following code demonstrates the problem:

using namespace std;
using namespace boost::interprocess;

typedef basic_ovectorstream<std::vector<char>, std::char_traits<char> > vecstream;
vecstream vs;

vs << "AAAABBBB";


// Output the contents of the internal vector
const std::vector<char>& vec = vs.vector();
for (int i = 0; i < vec.size(); ++i) cout << vec[i];
cout << endl;

This outputs: AAAAB

When it should output: AAAABBBB

Attachments (0)

Change History (6)

comment:1 Changed 9 years ago by anonymous

Component: Noneinterprocess
Owner: set to Ion Gaztañaga

comment:2 Changed 9 years ago by anonymous

This could be resolved by overloading xsputn in the vectorstream class in order to update the internal high water mark pointer after calling std::basic_streambuf<char_type, traits>::xsputn.

virtual std::streamsize xsputn(const char_type* s, std::streamsize n)
	std::streamsize ret = base_type::xsputn(s, n);
	if (mp_high_water < base_t::pptr()) mp_high_water = base_t::pptr();
	return ret;	

comment:3 Changed 9 years ago by chsalvia@…

Essentially, this bug happens because the vector stream class has a member function vector(), which returns a const reference to the internal vector. But, if the the vectorstream is an output stream, a call to vector() also resizes the vector:

 //!Returns a const reference to the internal vector.
   //!Does not throw.
   const vector_type &vector() const 
      if (this->m_mode & std::ios_base::out){
         if (mp_high_water < base_t::pptr()){
            //Restore the vector's size if necessary
            mp_high_water = base_t::pptr();
         m_vect.resize(mp_high_water - (m_vect.size() ? &m_vect[0] : 0));
         const_cast<basic_vectorbuf * const>(this)->initialize_pointers();
      return m_vect; 

Before resizing, the mp_high_water mark is set to the current position in the output sequence if it is less than pptr(). But, if a previous call to basic_vectorbuf::seekoff sets the stream position to 0, then the mp_high_water mark will not be changed, and the vector will be incorrectly resized.

comment:4 Changed 9 years ago by chsalvia@…

Actually, the best way to fix this is probably to update the high water mark when a call to seekoff() is made. That way, overloading xsputn is unnecessary, and sputc will work properly as well.

In basic_vectorbuf<CharVector?, Traits>::seekoff(), the following line could be added to fix the problem:

if (mp_high_water < base_type::pptr()) mp_high_water = base_type::pptr();

comment:5 Changed 9 years ago by Ion Gaztañaga

Fixed for Boost 1.40

comment:6 Changed 9 years ago by Ion Gaztañaga

Resolution: fixed
Status: newclosed

Modify Ticket

Change Properties
Set your email in Preferences
as closed The owner will remain Ion Gaztañaga.
The resolution will be deleted.

Add Comment

E-mail address and name can be saved in the Preferences.

Note: See TracTickets for help on using tickets.