Opened 13 years ago
Closed 13 years ago
#3166 closed Bugs (fixed)
Possible Bug in Boost.Interprocess vectorstream
Reported by: | Owned by: | Ion Gaztañaga | |
---|---|---|---|
Milestone: | Boost 1.40.0 | Component: | interprocess |
Version: | Boost 1.39.0 | Severity: | Problem |
Keywords: | Cc: |
Description
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"; vs.seekp(0); // 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
Change History (6)
comment:1 by , 13 years ago
Component: | None → interprocess |
---|---|
Owner: | set to |
comment:2 by , 13 years ago
comment:3 by , 13 years ago
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 by , 13 years ago
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:6 by , 13 years ago
Resolution: | → fixed |
---|---|
Status: | new → closed |
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.