简体   繁体   中英

Error “vector iterators incompatible” when concatenating two STL vectors

Following the advice on this question , I am attempting to do just that. However, at runtime I get an error "vector iterators incompatible", in the following:

std::vector<SE> all;
all.insert(all.end(),p->ev.begin(),p->ev.end());

where class pointed to by p contains a member

std::vector<SE> ev;

It is possible for the vector ev to be empty, in which case I want 'all' to be unchanged. Otherwise, I want all the elements of p->ev to be added to 'all', in the same order, at the end of 'all'.

What am I doing wrong?

Visual Studio 2010 C++, 32-bit Windows XP

ADDITIONAL INFO: Using the debugger, I have traced the proximate cause of the error message as the "owning container" of p->ev.begin() being 0. I have no clue what the "owning container" means.

My first thought is to try something like this

if(!p->ev.isEmpty())
{
   foreach(SE record in p->ev)
   {
      all.insert(SE);
   }
}

UPDATE: I didn't see you link at first, but will leave my anwser.

I tried this and it seemed to work ok

#include <vector>
#include <iostream>

struct P {
    P() {
        ev.push_back(3);
        ev.push_back(4);
    }
    std::vector<int> ev;
};

int main(int argc,char** argv) {
    std::vector<int> all;
    all.push_back(1);
    all.push_back(2);

    P* p = new P();
    all.insert(all.end(),p->ev.begin(),p->ev.end());
    copy(all.begin(),all.end(),std::ostream_iterator<int>(std::cout));
        delete p;
    return 0;
}

The only thing I could thing of giving that error would be if the SE type is redefined somewhere (maybe a typedef?). For the above example using basic types there shouldn't be an issue.

Produces 1,2,3,4 in order. If ev is empty, then we get 1,2 as you asked

Apparently this is a bug in Visual Studio 2010.

Visual Studio has a feature "Checked Iterators". In a debug build, every iterator operation is chacked at runtime for errors, eg, out of range. My pgm failed one of these checks, namely, that the iterators for the range for the vector being inserted were from the same collection class (ie, in this case, from the same vector). As you can see from my code sample, they were, so the test result was incorrect.

The test worked correctly if the vector being inserted (p->ev in my example) was in the same class as the destination vector ('all'), but not if the vector being inserted was in a different class. That's one reason why Ronnie didn't see the problem, even if he was using VS 2010.

For anyone who may run into this same difficulty, the "cure" is to disable the iterator checking, by defining C++ preprocessor variable _ITERATOR_DEBUG_LEVEL as 0. The Microsoft documentation on use of _SECURE_SCL for this purpose is incorrect.

With checking disabled, everything works as expected.

A similar bug was reported, and allegedly fixed, in VS 2010 in connection with 'erase'.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM