Не использовать итераторы в векторах с измененным размером - PullRequest
2 голосов
/ 22 января 2010

Я читаю на языке программирования C ++: Special Edition

Don't use iterators into a resized vector

Рассмотрим этот пример.

vector< int >::iterator it = foo.begin();

while ( it != foo.end() ) {
  if ( // something ) {
    foo.push_back( // some num );
  }
  ++it;
}

Есть ли проблема с этим? После изменения размера вектора foo.end () в условии цикла будет перемещен вперед на 1?

P.S. Кроме того, что делать, если вектор зарезервировал место для числа х целых. Если push_back не нарушает это пространство, это все равно будет проблемой (я бы предположил, что если it.end () будет указывать на один последний элемент в векторе, который содержит что-то).

Ответы [ 4 ]

5 голосов
/ 22 января 2010

Да, есть проблема с ним.

Любой вызов push_back потенциально может сделать недействительными всех итераторов в векторе.

foo.end() всегда будет получать действительный конечный итератор (который может отличаться от значения, последнего возвращенного foo.end()), но it может быть недействительным. Это означает, что увеличение или сравнение может привести к неопределенному поведению.

1 голос
/ 22 января 2010

Да, есть проблема с этим. push_back делает недействительными любые итераторы для вектора, на котором вы его вызвали. Поэтому после вызова push_back выполнение ++it даже не разрешено. Это случай неопределенного поведения, поэтому оно может иногда работать, а иногда и не работать, но вы никогда не должны полагаться на его работу.

1 голос
/ 22 января 2010

Да, есть проблема. Независимо от foo.end(), it может быть аннулирован push_back(). Редактировать: (то есть не просто , что конец может измениться; возможно, что весь буфер для вектора может быть перераспределен, поэтому все итераторы станут недействительными) .

0 голосов
/ 22 января 2010

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

...