Vector Iterators Incompatible

Vector Iterators Incompatible

The reason you are getting this, is that the iterators are from two (or more) different copies of myVec. You are returning a copy of the vector with each call to myFoo.getVec(). So the iterators are incompatible.

Some solutions:

Return a const reference to the std::vector<int> :

const std::vector<int> & getVec(){return myVec;} //other stuff omitted

Another solution, probably preferable would be to get a local copy of the vector and use this to get your iterators:

const std::vector<int> myCopy = myFoo.getVec();
std::vector<int>::const_iterator i = myCopy.begin();
while(i != myCopy.end())
{
//do stuff
++i;
}

Also +1 for not using namespace std;

Debug Assertion : Vector iterators incompatible (C++)

You have not posted enough code to be really sure, but the following guess should be correct:

getElements() most likely returns by value, not by reference.

For example:

std::vector<std::shared_ptr<GameGridElement>> Field::getElements()
{
// ...
return result;
}

This returns a copy! Which means that every time you call getElements, you get a different vector.

For the compiler, this does not make any difference. Type safety does not help you, because a std::vector<std::shared_ptr<GameGridElement>>::iterator is a std::vector<std::shared_ptr<GameGridElement>>::iterator, even if you have two iterators which belong to different container instances. They have the same type, so the code compiles.

At run time, however, additional checks can be made to ensure that two iterators that are being compared really belong to the same container object. This turns seemingly random "strange" behaviour or spurious crashes into a definite guaranteed crash to immediately tell you that something must be fixed.

Consider again this line:

for (
std::vector<std::shared_ptr<GameGridElement>>::iterator
it = m_pGameField->getField(i, j)->getElements().begin();
it != m_pGameField->getField(i, j)->getElements().end();
++it
)

it is initialised to getElements().begin() and is then compared by != to getElements().end(). But as explained above, each getElements() returns a different vector, so you get incompatible iterators.

Here is an easy way to solve the problem:

std::vector<std::shared_ptr<GameGridElement>> elements =
m_pGameField->getField(i, j)->getElements();

for (std::vector<std::shared_ptr<GameGridElement>>::iterator it = elements.begin();
it != elements.end(); ++it)

This makes sure that begin() and end() return iterators to the same container instance.


For reference, here is a simple piece of code to reproduce the behaviour:

#include <vector>

int main()
{
std::vector<int> v1;
std::vector<int> v2;

bool b = v1.begin() == v2.begin();
}

Note that the C++ standard does not mandate iterator-compatibility checks at run time. Your compiler has to offer them and you must use the correct compiler options to enable them, or disable them if you don't need them or cannot afford them.


By the way, if you can use C++11, then you can use a range-based for loop to not only fix the bug but also make the code a lot more concise.

Vector Iterators Incompatible when calculating distance between two iterators

vector::insert invalidates the iterators. In expression insert(object) - begin() begin() can be called before or after insert. If it is called before than it is invalidated by insert(). Order of evaluation:

Order of evaluation of the operands of almost all C++ operators (including the order of evaluation of function arguments in a function-call expression and the order of evaluation of the subexpressions within any expression) is unspecified. The compiler can evaluate operands in any order, and may choose another order when the same expression is evaluated again.

Whereas when you do:

const_iterator (or auto) it = insert(object);
return it - begin();

begin() is called after insert() and hence returns a valid iterator.

Why am I getting vector iterators incompatible?

Iterators corresponding to elements are only invalidated when the vector has to be reallocated, which reserve avoids.

However, v.end() won't stay valid.

The Standard's description of push_back and insert guarantees that

Causes reallocation if the new size is greater than the old capacity. If no reallocation happens,
all the iterators and references before the insertion point remain valid.

v.end() is not "before the insertion point".

C++ `vector iterators incompatible` error only in Visual Studio

Your object has a rule of three violation - on copy/move construction the iterator will still point to the vector in the old object.

The line WordCrawler wc = WordCrawler(in, true); specifies a copy/move operation, triggering this problem. Most compilers perform copy elision here but I heard that older versions of MSVC don't, in debug mode anyway.

To fix this properly, I would recommend using an index instead of an iterator in the class. If you really want to use the iterator you will need to implement your own copy-constructor and move-constructor.

Changing that line to WordCrawler wc(in, true); would probably fix this particular program but the same problem would be lurking still, and might show up when you make further modifications later.

Vector Iterators Incompatible: proper way to iterate over two vectors?

The way to do this is to hold internally two iterators. One to vec1, the other to vec2. First use the first one, then after the first one reaches the end of vec2 switch to the other one.

Some snippets to see what I mean:

itnerator& operator++()
{
if (it1 != vec1.end())
++it1;
else
++it2;
return *this;
}
std::string& operator*()
{
if (it1 != vec1.end())
return *it1;
else
return *it2;
}

C++ for-each statement triggers vector iterators incompatible assertion failure: this-_Getcont() == 0

I finally found the problem. A path deep in the vector's setup code was clobbering the vector's state (memset'ing it to 0's as part of a larger chunk of memory). This caused no harm for the first three fields in vector: _Myfirst, _Mylast, and _Myend since those fields are 0 in an initial vector. Moreover, most things such as the array index operator and other methods such as push_back still functioned correctly. However, the fourth field _Myproxy was initially non-zero, and clearing it disabled iterator-based functionality. Hence, for-each loop, vector::back(), and others all fail with different false errors such as false bounds checks, false incompatible iterators, etc...

vector iterators incompatible. How can I pass it as a parameter to the function?

You return copy of vector in get_temperature, and so use iterator of temporary vector in

std::vector<float>::iterator i = t.get_temperature().begin()

Solution is to return reference:

class TemperatureCalculator {
private:
std::vector<float> temperatures;

// ...
public:
const std::vector<float>& get_temperature() const { return this->temperatures; }
// Possibly:
//std::vector<float>& get_temperature() { return this->temperatures; }
};

Notice that passing simple iterator seems strange whereas passing value do the job:

std::string klimaTag(float f) const
{
if (25 <= f and f < 30) {
return "Sommertag";
}
else if (30 <= f and f < 35) {
return "Heißer Tag";
}
else if (*35 <= f) {
return "Wüstentag";
}
else {
return "Normaltag";
}
}

and so your loop becomes:

for (float f : t.get_temperature()) {
std::cout << "Tag " << f + 1 << " ist ein " << t.klimaTag(f) << std::endl;
}

C++ STL vector iterators incompatible

Your code needs to become

while (iter != FDRFreq.end()){
if( iter->fData.size() < StandardNum){
iter = FDRFreq.erase(iter);
}
else{
++iter;
}
}

"vector iterators incompatible" means that the iterator you're using has been invalidated - that is to say, there is no guarantee that the elements it points to still exist at that memory location. An erase of a vector element invalidates the iterators following that location. .erase returns a new, valid iterator you can use instead.

If you're new to STL, I highly recommend you read Scott Myer's Effective STL (and Effective C++, while you're at it)

Why are the iterators not compatible?

Your error doesn't have anything to do with strings or ints or conversions. It's because you're creating a new copy of vector<string> word every time you call findString, and so its returned iterator is an iterator of a different vector (it's an iterator into a copy). You have:

vector<string>::iterator findString(vector<string> word, string x)
{
...
}

And then later, where the error is:

vector<string>::iterator t = findString(word, x);

if (t != word.end()) //A: Error happens in this line.

And so findString is returning an iterator into a copy of word instead of word itself, and MS' vector implementation has an assertion failure when you try to compare it with an iterator from a different vector, because it figures you most likely made a mistake. Instead pass your vectors by reference, for example:

vector<string>::iterator findString(vector<string> & word, string x)
{
...
}

Note that word is now passed by reference, and so won't be copied.

That said, you should fix your error first as an exercise, of course, but after you've got your own code working, consider replacing findString with std::find (since it already exists). Also it seems you can simplify your code greatly by using a map<string,int> to maintain word counts. And a few other things.



Related Topics



Leave a reply



Submit