chenyuandong
chenyuandong

Reputation: 296

Why is iterator of container invalidated when this container is also an element of a container?

int main() {
    std::vector<std::vector<int>> v;
    v.push_back({1,2,3,4});

    auto it = v.at(0).begin();
    int size = v.at(0).size();
    std::cout<<size<<std::endl;
    for (int i = 0; i < size; ++it)
    {
        v.push_back({5,6,7,8});
        //std::cout<<*it<<std::endl;
    }

    return 0;
}

The iterator is broken when I push some elements into the outer container. what should I do if I really want to iterate the container element inside of outer container and at the same time keep pushing back some new elements ? Many thanks!

Upvotes: 1

Views: 69

Answers (2)

Chris Uzdavinis
Chris Uzdavinis

Reputation: 6131

When the outer vector resizes, it must do one of two things:

  • copy the elements
  • move the elements

It can only move the elements if the type has nonthrowing move semantics (the move constructor is marked noexcept, etc).

In this case, the element is a vector holding integers, which recursively depends on its elements. Since integer does not throw, the inner vector should be noexcept-movable too. The standard requires the iterators to remain valid when moving such a vector.

You say iterator is broken in your example, but the real problem is a bug in your code:

for (int i = 0; i < size; ++it) // << HERE
{
    v.push_back({5,6,7,8});
    //std::cout<<*it<<std::endl;
}

You don't increment the loop variable, you increment the iterator, in an infinite loop

Upvotes: 2

Slava
Slava

Reputation: 44238

what should I do if I really want to iterate the container element inside of outer container and at the same time keep pushing back some new elements ?

I see 3 possible solutions:

  • use container that does not relocate elements when new ones are added, for example std::map<size_t,std::vector<int>>, you should be aware of different memory usage and access speed

  • use index of inner array instead of iterator

  • add data to a temporary vector in the loop and after you done append all data to the original vector

Upvotes: 0

Related Questions