Opened 7 years ago

Last modified 7 years ago

#11609 new Bugs

circular_buffer erroneously invalidates reverse_iterator at pop_back in debug mode

Reported by: christian.stimming@… Owned by: Jan Gaspar
Milestone: To Be Determined Component: circular_buffer
Version: Boost 1.57.0 Severity: Problem
Keywords: Cc:

Description (last modified by viboes)

The circular_buffer container offers reverse iterators. Using one so that it points to the second-to-last element would in theory allow to pop_back() the last element without causing problems with that iterator. However, apparently pop_back() invalidates those reverse iterators even though they wouldn't cause problems, as if the debug_iterator_registry in boost/circular_buffer/debug.hpp is working correctly only for forward iterators but not for backward iterators.

Example code that works fine without debug mode, but will run into a failed assertion in debug mode:

#define BOOST_CB_ENABLE_DEBUG
#include <boost/circular_buffer.hpp>
#include <iostream>
int main(int /*argc*/, char** /*argv*/) {
	typedef boost::circular_buffer<int> CircBuffer;
	CircBuffer testBuffer(2);
	testBuffer.push_back(4);
	testBuffer.push_back(8);

	CircBuffer::const_reverse_iterator bufIter = testBuffer.rbegin();
	std::cout << "element at rbegin=" << *bufIter << std::endl; // prints "=8" correctly
	++bufIter;
	std::cout << "element after ++=" << *bufIter << std::endl; // prints "=4" correctly
	testBuffer.pop_back();
	std::cout << "elem=" << *bufIter << std::endl; // ERROR: Causes "Assertion `is_valid(m_buff)' failed."
}

Change History (2)

comment:1 by christian.stimming@…, 7 years ago

Sorry, here the code again in readable form:

#define BOOST_CB_ENABLE_DEBUG
#include <boost/circular_buffer.hpp>
#include <iostream>
using namespace std;
int main(int /*argc*/, char /*argv*/) {
  typedef boost::circular_buffer<int> CircBuffer;
  CircBuffer buffer(2);
  buffer.push_back(4);
  buffer.push_back(8);

  CircBuffer::const_reverse_iterator iter = buffer.rbegin();
  cout << "elem=" << *iter << endl; // prints "=8" correctly
  ++iter;
  cout << "elem=" << *iter << endl; // prints "=4" correctly
  buffer.pop_back();                // ERROR: invalidates the iterator
  cout << "elem=" << *iter << endl; // ERROR: Causes "Assertion `is_valid(m_buff)' failed." instead of printing "=4"
} 

comment:2 by viboes, 7 years ago

Component: Nonecircular_buffer
Description: modified (diff)
Owner: set to Jan Gaspar
Note: See TracTickets for help on using tickets.