C/C++ Arena

Step 6 of 7

Iterator invalidation

Changing a container can invalidate iterators, pointers and references into it. Using one afterwards is undefined behavior, and one of the most common C++ bugs in real code:

Container What invalidates
vector push_back that reallocates: everything. erase: the erased element and everything after it
deque inserting at either end invalidates iterators (but not references)
list, map, set only iterators to erased elements

The safe erase-while-looping pattern uses the iterator erase returns (the element after the removed one):

for (auto it = v.begin(); it != v.end(); ) {
    if (dead(*it)) it = v.erase(it);   // don't ++ after erasing
    else ++it;
}

(For vectors, std::erase_if(v, pred) does this in one efficient call, as you saw in the algorithms module. The loop pattern is still what you need for map and for loops that do more than erase.)

Your turn: write int remove_expired(std::map<std::string, int>& sessions, int now) that erases every session whose expiry time is <= now, returning how many were removed. Use the loop pattern.

Previous: Iterators Next: Challenge: callbacks with std::function