C ++ for each statement runs "vector incompatible iterators." Approval Error: this & # 8594; _ Getcont () == 0

This is with Visual Studio 2012.

static void func(
  ...,
  const std::vector<std::string> &opt_extra_args_strs,
  ...)
{
   // THIS ASSERTS: "vector iterators incompatible"
   for (const std::string &arg_str : opt_extra_args_strs) {
      ... body does not modify opt_extra_args_strs

   // BUT THIS WORKS:
   for (size_t a_ix = 0; a_ix < opt_extra_args_strs.size(); a_ix++) {
       const std::string &arg_str = opt_extra_args_strs[a_ix];
}

I do not change the vector at all in the body of the loop, and in fact the statement occurs before the first iteration. The vector looks correct in the debugger, but I don’t know enough about the STL to look for corruption. Inside the STL, an assertion error occurs from:

void _Compat(const _Myiter& _Right) const {
    // test for compatible iterator pair
    if (this->_Getcont() == 0 // THIS FAILS (_Getcont() == 0)
         ...) {
        _DEBUG_ERROR("vector iterators incompatible");

with this->_Getcont()equal to NULL, because ( _Myproxyequal to NULL in _Iterator_base12). Call stack:

msvcp110d.dll!std::_Debug_message(const wchar_t * message, const wchar_t * file, unsigned int line) Line 15 C++
Main.exe!std::_Vector_const_iterator<std::_Vector_val<std::_Simple_types<std::basic_string<char,std::char_traits<char>,std::allocator<char> > > > >::_Compat(const std::_Vector_const_iterator<std::_Vector_val<std::_Simple_types<std::basic_string<char,std::char_traits<char>,std::allocator<char> > > > > & _Right)
Main.exe!std::_Vector_const_iterator<std::_Vector_val<std::_Simple_types<std::basic_string<char,std::char_traits<char>,std::allocator<char> > > > >::operator==(const std::_Vector_const_iterator<std::_Vector_val<std::_Simple_types<std::basic_string<char,std::char_traits<char>,std::allocator<char> > > > > & _Right)
Main.exe!std::_Vector_const_iterator<std::_Vector_val<std::_Simple_types<std::basic_string<char,std::char_traits<char>,std::allocator<char> > > > >::operator!=(const std::_Vector_const_iterator<std::_Vector_val<std::_Simple_types<std::basic_string<char,std::char_traits<char>,std::allocator<char> > > > > & _Right)
Main.exe!run_test(..., const std::vector<std::basic_string<char,std::char_traits<char>,std::allocator<char> >,std::allocator<std::basic_string<char,std::char_traits<char>,std::allocator<char> > > > & opt_extra_args_strs)
    ...

I suspect that the code creating the vector somehow screwed it, but I'm not sure. It’s also difficult for me to write a simpler reproducing one, but the program must be completely deterministic (single-threaded, not random variables, always states).

, "vector iterator + offset out of range" ( )

template <typename T>
class Elsewhere {
    virtual void earlier(
        ....
        std::vector<T> &v) const
    {
       v.emplace_back(); // empty construction of a T
      // T &t = v.back(); // assertion failure
      T &val = to[to.size() - 1]; // but this works
      ... mutates val.

T = std::string (, ).

, STL this->_Getcont() == 0, , . , _Getcont() 0 Vector_const_iterator?

template <typename T>
struct type {
   T m_value;

   operator const T &() const {
     return value();
   }

   const T &value() const {
       return m_value;
   }
};

type<std::vector<std::string>> &t = ... method call that returns ref to it;
... t gets set
func(t); // implicit conversion to (const std::vector<std::string> &)
+3
3

- . (memset'ing 0 ). : _Myfirst, _Mylast _Myend, 0 . , , , push_back, . _Myproxy . , vector::back() , , ..

+3

, ++ 11 , 100 . . .

, http://www.stroustrup.com/C++11FAQ.html#for. , (, , ). , , . ( ):

// added a local string to clearly indicate types
std::string s1;
const std::string &arg_str = s1;


const std::vector<std::string> :: iterator i;
i = opt_extra_args_strs.begin(); // happens inside the range for

for (arg_str = i; i < opt_extra_args_strs.end(); i++)
{
   // loop body
}

arg_str , .

for , , , , , , . , ( , ) . .

, . , auto , ( , ++ 11 ).

T &t = v.back(); // assertion failure

( " " ).

back() - STL . . , , , () , ().

end(): T & t , std :: vector<T> :: iterator, , v.end(). :

 T &t = std::vector<T> :: iterator

std::vector:: back(), back() , undefined. , . : http://www.cpluscplus.com/reference/vector/vector/back. , (), , , , . , emplace_back(Args&&... args); http://www.cpluscplus.com/reference/vector/vector/emplace_back, , , : " allocator_traits:: construct , undefined". , , - :

//
// start of the 'earlier' function body 
//
std::string s;
v.emplace_back(s); // add one element to v

//
// obtain a reference to the last element (should be a copy of s above)
//
T &t = v.back(); 



//
// It is not clear what the vector 'to' is and how it exists inside 'earlier'
// as long as 'to' has at least one element, then the code below will 
// set the local reference variable to the last element of 'to'.  
// If not, then another run time error is likely with attempting to access to[-1]
// and then attempting to assign the non-existent element to T& val
//
T &val = to[to.size() - 1];

, , , .

( )

, . Visual Studio 2012 ++. , stl.

+1

I myself came across this statement. I found that the reason that what I called in the loop was a change in the vector that I was executing with.

+1
source

All Articles