Инвалидность итератора после вызова стирания - PullRequest
2 голосов
/ 16 февраля 2012

Я немного смущен.Я узнал или сказал, что итератор вектора становится недействительным, если вызывается erase.Но почему код ниже работает.Он скомпилирован с использованием g ++ и работает в 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;
}

Спасибо за любые отзывы!

Ответы [ 3 ]

2 голосов
/ 16 февраля 2012

С http://www.cplusplus.com/reference/stl/vector/erase/ (не самый лучший в мире справочник по C ++):

Это делает недействительным весь итератор и ссылки на позицию (или первую) и ее последующие элементы.

То есть it недействительно;использование его приводит к неопределенному поведению .Тот факт, что вы получили то, что вы ожидаете, является чистой неудачей.

1 голос
/ 16 февраля 2012

То, что вы делаете - это неопределенное поведение, и то, что оно " работает ", совершенно случайно. Вы не можете и не должны когда-либо полагаться на это, потому что это может сделать что угодно. Поведение его не определено.

0 голосов
/ 16 февраля 2012

В качестве детали реализации, vector<int>::iterator может легко быть int*.Я думаю, что в g++ это очень тонкая оболочка вокруг int*.Если это так, то удаление среднего элемента трехэлементного вектора означает, что элемент данных указателя it остается указанным по тому же адресу, что и удаленный элемент, который, конечно, будет содержать значение, которое ранее было прямым послеэто, и которое также справедливо упоминается it2.

Стандарт не гарантирует, что it все еще будет ссылаться на что-либо, поэтому вы не можете полагаться на поведение, которое вы наблюдалиВот.Но это объясняет, что вы видели.Реализация в значительной степени должна делать все возможное, чтобы что-то еще происходило, когда вы разыменовываете it.Но компиляторы каждый день стараются изо всех сил: например, отладка версий библиотек, а некоторые методы оптимизации основаны на предположениях о том, что ваш код верен.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...