ProblemsUB & GotchasErasing while iterating
IntermediateUB & Gotchas

Erasing while iterating

Context

Bug report: 'sometimes the filter doesn't remove everything'. Sometimes! QA is furious, the developer is on vacation, and the code has a loop calling erase and then marching on with an invalidated iterator. Works on scattered data, fails on adjacent duplicates. erase returns the next iterator for a reason: take it.

Task

removeEvens calls v.erase(it) and keeps using it — but erase invalidates the iterator. Using it afterwards is undefined behaviour, and even when it "works", adjacent matches get skipped. Use the iterator that erase returns.

Constraints

  • Use the iterator returned by erase (or restructure with the erase-remove idiom)
  • Never increment or dereference an invalidated iterator
  • Adjacent even numbers are all removed
  • The relative order of the kept elements is preserved

Before you code

  • Exactly which iterators does vector::erase invalidate?
  • Why does the buggy loop skip the second of two adjacent evens?
  • When would you prefer erase-remove over the erase-returns-next loop?

Tests

  • #1Removes evens, keeps odds in order
  • #2Adjacent evens are all removed
  • #3All-even vector becomes empty

Hints

Hint 1

Move the increment inside the loop: if (even) it = v.erase(it); else ++it; — and drop ++it from the for-header.

Editoriterator-after-erase.cpp
Results

Hit Submit (or ⌘/Ctrl + ↵) — test results will show up here.