Orunner
Orunner

Reputation: 424

Iterator invalidity after calling erase

I am confused a bit. What I have learned or been told is that an iterator of a vector becomes invalid if erase is called. But why the code below works. It is compiled using g++ and run in Linux.

#include <vector>
#include <iostream>

using namespace std;

int main() {
  vector<int> vec;
  vec.push_back(1);
  vec.push_back(2);
  vec.push_back(3);

  vector<int>::iterator it = vec.begin();
  ++it;
  vector<int>::iterator it2;

  it2 = vec.erase(it);
  cout << "it: " << *it << endl;
  cout << "it2: " << *it2 << endl;
}

Thanks for any feedbacks!

Upvotes: 2

Views: 205

Answers (3)

Steve Jessop
Steve Jessop

Reputation: 279445

As an implementation detail, vector<int>::iterator can easily be int*. I think in g++ it's a very thin wrapper around an int*. If that's the case, then erasing the middle element of a three-element vector means that the pointer data member of it is left pointing at the same address as the element removed, which of course will contain the value that previously was straight after it, and which is also validly referred to by it2.

The standard does not guarantee that it will still refer to anything, which is why you can't rely on the behavior you've observed here. But it explains what you've seen. An implementation pretty much has to go out of its way to make anything else happen when you dereference it. But compilers do go out of their way every day: debugging versions of the libraries for example, and some optimization techniques rely on assumptions that your code is correct.

Upvotes: 0

Tony The Lion
Tony The Lion

Reputation: 63310

What you're doing is Undefined Behaviour, and that it "works" is entirely accidental. You cannot and must not ever rely on this, because it could do just about anything. The behaviour of it is not defined.

Upvotes: 1

Oliver Charlesworth
Oliver Charlesworth

Reputation: 272802

From http://www.cplusplus.com/reference/stl/vector/erase/ (not the world's best C++ reference):

This invalidates all iterator and references to position (or first) and its subsequent elements.

So it is invalid; using it results in undefined behaviour. The fact that you happen to get what you expect is pure bad luck.

Upvotes: 2

Related Questions