2013-06-27 4 views
0

std::vector итераторы могут быть реализованы как указатели. Следствием является то, что если вы добавите элементы в вектор, выдающиеся итераторы, очевидно, станут недействительными, потому что в общем случае векторные данные должны быть перераспределены.Неверные векторные итераторы

Первое предположение относительно точных правил заключается в том, что разрешенные операции точно такие же, как и для указателей, например. не разыгрывайте недействительный итератор до тех пор, пока оно не будет переназначено допустимым значением, но это, похоже, не совсем верно, потому что реализация Microsoft в режиме отладки иногда вызывает исключение, если вы, например. вычесть векторные итераторы, указывающие на разные блоки данных (что полезно для отладки, если быть уверенным).

Является ли добавление к указателю правил чем-то вроде «не вычитать итераторы для разных блоков данных» или «не выполнять арифметику на недействительном итераторе до тех пор, пока оно не будет переназначено действительным значением» или что-то еще?

Например, действительна ли следующая программа (которая работает как на Microsoft C++, так и на GCC)?

#include <algorithm> 
#include <iostream> 
#include <vector> 

using std::cout; 
using std::ostream; 
using std::vector; 

template<class T> ostream& operator<<(ostream& os, vector<T>& v) { 
    os << '['; 
    bool c = 0; 
    for (auto a: v) { 
     if (c) 
      os << ", "; 
     c = 1; 
     os << a; 
    } 
    return os << ']'; 
} 

void f(vector<int>& v, vector<int>::iterator& i) { 
    *i = 10; 
    for (int j = 0; j < 10; j++) 
     v.insert(begin(v), j); 
    i = begin(v)+5; 
} 

int main() { 
    vector<int> v; 
    for (int i = 0; i < 10; i++) 
     v.push_back(i); 
    auto i = begin(v)+5; 
    f(v, i); 
    i[1] = 11; 
    cout << v << '\n'; 
    return 0; 
} 
+0

Что именно вы подразумеваете под «итераторами, указывающими на разные блоки данных»? – jogojapan

+0

И почему пример программы недействителен? В какой момент происходит что-то, что вы считаете недействительным? – jogojapan

+0

@jogojapan разные векторы или элементы одного и того же вектора до и после добавления новых элементов вызвали перераспределение. – rwallace

ответ

-1

Ваш пример недействителен, причина его успеха - удача. Каждая операция, которая может привести к перераспределению в векторе, может привести к аннулированию всех итераторов.

+0

Не могли бы вы объяснить, в какой части кода вы конкретно ссылаетесь? Также обратите внимание, что просто аннулирование итератора не означает, что программа недействительна. Это просто означает, что есть определенные вещи, которые вы не должны делать с этим итератором. – jogojapan