0

Say I have something like this:

void myFunk(std::vector<T>& v, std::vector<T>::iterator first, std::vector<T>::iterator last) {
    while (first != last) {
        if ((*first) > (*last)) {
            T someT;
            v.push_back(someT);
        }
        first++;
    }
}

int main(){
    std::vector<T> foo = {some, T, values};
    myFunky(foo, foo.begin(), foo.end())
    return 0;
}

Would this lead to an infinite loop, or would it end after foo.size() iterations? In other words, would the last iterator be updated as foo grew, or would it retain the value given in the function call?

I'm assuming last would change, since it's a pointer to a position, but would like some confirmation.

General Grievance
  • 4,555
  • 31
  • 31
  • 45

1 Answers1

0

Would this lead to an infinite loop, or would it end after foo.size() iterations?

Neither. What you are doing is undefined behavior, for a couple of reasons:

  • You are modifying the vector while iterating through it.

    If the vector reallocates its internal storage when pushing a new item, all existing iterators into the vector are invalidated, including both iterators you are using to loop with. But even just pushing a new item always invalidates the end() iterator, at least.

    See Iterator invalidation rules for C++ containers

  • You are dereferencing the end() iterator, which never refers to a valid element.

I'm assuming last would change, since it's a pointer to a position

It can't change, since you passed it into the myFunc function by value, so it is a copy of the original end() iterator. If end() changes value, last will not change value, since it is a copy.

In any case, iterators are not necessarily implemented as pointers, but pointers are valid iterators. But it doesn't matter in this case. Even if vector::iterator were just a simple pointer, last would still get invalidated upon every push/reallocation.

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
  • Passing by value was deliberate - the idea was to *try* to make the vector iterate in the current values, while appending new ones at the end. Makes sense i was getting memory access violations at run-time. Thanks for the invalidation rules plug (I knew what i was looking for was documented but didn't know how to verbalize it). And thanks for the answer man. Really cleared things up. Cheers! – Pedro Barbeira Nov 18 '21 at 17:17
  • I would suggest caching the inserts to a local vector, and then append that to the end of the target vector after the iteration is finished. – Remy Lebeau Nov 18 '21 at 21:21