vector.erase
От: SmileIlya  
Дата: 02.07.10 09:37
Оценка:
перевожу с VC 5.0 на VC 2008

есть конструкция
std::vector<T*>::iterator it = V.begin();
for (; it != V.end(); ++it)
{
if(условие)
V.push_back(значение);
V.erase(it);
--it;
}
в VC 5.0 все прокатывало на ура.... vc2008 компилится нормально, но вот работать отказывается, пишет при --it ошибку и падает.
Re: vector.erase
От: Sni4ok  
Дата: 02.07.10 09:40
Оценка:
попробуйте

SI> V.erase(it);

SI> --it;
SI>}

заменить на
it = V.erase(it);
Re[2]: vector.erase
От: SmileIlya  
Дата: 02.07.10 09:45
Оценка:
Здравствуйте, Sni4ok, Вы писали:

S>попробуйте


SI>> V.erase(it);

SI>> --it;
SI>>}

S>заменить на

S>
S>it = V.erase(it);
S>


пробовал и такое, если бы не было bush_back все прокатывало... как только его(push_back) добавляешь, значение it меняются сразу и erase не работает
Re[3]: vector.erase
От: Sni4ok  
Дата: 02.07.10 09:48
Оценка: 1 (1)
Здравствуйте, SmileIlya, Вы писали:

SI>пробовал и такое, если бы не было bush_back все прокатывало... как только его(push_back) добавляешь, значение it меняются сразу и erase не работает


разумеется итераторы после push_back'а у вектора могут стать невалидными в силлу того, что например произойдёт переаллокация памяти, запомните индекс элемента, и удаляйте по нему.
Re: vector.erase
От: abrec Россия  
Дата: 02.07.10 09:49
Оценка: +1
Здравствуйте, SmileIlya, Вы писали:

SI>перевожу с VC 5.0 на VC 2008


SI>есть конструкция

SI>std::vector<T*>::iterator it = V.begin();
SI>for (; it != V.end(); ++it)
SI>{
SI> if(условие)
SI> V.push_back(значение);
SI> V.erase(it);
SI> --it;
SI>}
SI>в VC 5.0 все прокатывало на ура.... vc2008 компилится нормально, но вот работать отказывается, пишет при --it ошибку и падает.
SI>

так делать нельзя. после удаления элемента в векторе итераторы могут стать невалидными.
Re: vector.erase
От: uzhas Ниоткуда  
Дата: 02.07.10 10:08
Оценка: 5 (5)
Здравствуйте, SmileIlya, Вы писали:

SI>перевожу с VC 5.0 на VC 2008


SI>есть конструкция

конструкция некорректная, ибо внутри цикла инвалидируются итераторы вектора
вам уже посоветовали работать с индексами, а не с итераторами
я могу вам посоветовал в цикле сделать копирование элементов в другой вектор. это может сделать ваш алгоритм более ясным и корректным
в таком духе:
std::vector<T*> newV;
std::vector<T*>::const_iterator it = V.begin();
for (; it != V.end(); ++it)
{
  if (условие)
    newV.push_back(значение);
}
V.swap(newV);
Re: vector.erase
От: Bell Россия  
Дата: 02.07.10 10:08
Оценка:
Здравствуйте, SmileIlya, Вы писали:

SI>перевожу с VC 5.0 на VC 2008


SI>есть конструкция

SI>std::vector<T*>::iterator it = V.begin();
SI>for (; it != V.end(); ++it)
SI>{
SI> if(условие)
SI> V.push_back(значение);
SI> V.erase(it);
SI> --it;
SI>}
SI>в VC 5.0 все прокатывало на ура.... vc2008 компилится нормально, но вот работать отказывается, пишет при --it ошибку и падает.
SI>


Быть может индексы ?

for(int i = 0; i < (int)V.size(); ++i)
{
   if(...)
      V.push_back(...);
   V.erase(V.begin() + i--);
}


Хотя выглядит все это как-то очень подозрительно....
Не проще завести новый вектор, сложить в него все, что нужно, и потом свапнуть с исходным?
Любите книгу — источник знаний (с) М.Горький
Re: vector.erase
От: Тот кто сидит в пруду Россия  
Дата: 02.07.10 11:12
Оценка:
Здравствуйте, SmileIlya, Вы писали:

SI>перевожу с VC 5.0 на VC 2008


SI>есть конструкция

SI>std::vector<T*>::iterator it = V.begin();
SI>for (; it != V.end(); ++it)
SI>{
SI> if(условие)
SI> V.push_back(значение);
SI> V.erase(it);
SI> --it;
SI>}
SI>в VC 5.0 все прокатывало на ура.... vc2008 компилится нормально, но вот работать отказывается, пишет при --it ошибку и падает.
SI>

И какое желаемое поведение? Оно в результате должно удалить из вектора все элементы или зациклиться, вечно вставляя и удаляя удовлетворяющие условию элементы?
Одним из 33 полных кавалеров ордена "За заслуги перед Отечеством" является Геннадий Хазанов.
Re[2]: vector.erase
От: SmileIlya  
Дата: 02.07.10 11:21
Оценка:
Всем большое спасибо, суть в том, что не всегда срабатывает условие.. а по пройденным могут появится новые значения.(использовал индексы)
Re: vector.erase
От: Smooky Россия  
Дата: 03.07.10 19:41
Оценка:
C. Мейерс. "Эффективное использование STL"
Совет №9, стр. 53.

"...поскольку для контейнеров vector. string и deque в результате вызова
erase становятся недействительными все итераторы, указывающие на удаляемый
элемент. Кроме того, недействительными становятся все итераторы после
удаляемого элемента.
...
Мы должны воспользоваться возвращаемым значением erase, которое содержит
именно то, что нам требуется — действительный итератор, который указывает на
элемент, следующий за удалённым.

for (ПоследовательныйКонтейнер<T>::iterator=c.begin(); i!=c.end()
{
if (Условие(*i))
i=c.erase(i);
else
++i;
}
"
Posted via RSDN NNTP Server 2.1 beta
Только Путин, и никого кроме Путина! О Великий и Могучий Путин — царь на веки веков, навсегда!
Смотрю только Соловьева и Михеева, для меня это самые авторитетные эксперты.
КРЫМ НАШ! СКОРО И ВСЯ УКРАИНА БУДЕТ НАШЕЙ!
Re[2]: vector.erase
От: sgenie  
Дата: 05.07.10 03:15
Оценка:
А я бы сделал вот так:

c.erase(i++);


S>for (ПоследовательныйКонтейнер<T>::iterator=c.begin(); i!=c.end()

S>{
S> if (Условие(*i))
S> i=c.erase(i);
S> else
S> ++i;
S>}
S>"
Re[3]: vector.erase
От: uzhas Ниоткуда  
Дата: 05.07.10 06:00
Оценка:
Здравствуйте, sgenie, Вы писали:

S>А я бы сделал вот так:

S> c.erase(i++);

так можно делать только для ассоциативных контейнеров, но не для последовательных
читайте, что написал Smooky
Re[4]: vector.erase
От: sgenie  
Дата: 05.07.10 21:28
Оценка:
Da, uzhe ponyal, chto ya dlya map pisal, a obsuzhdalsya vector


Здравствуйте, uzhas, Вы писали:

U>Здравствуйте, sgenie, Вы писали:


S>>А я бы сделал вот так:

S>> c.erase(i++);

U>так можно делать только для ассоциативных контейнеров, но не для последовательных

U>читайте, что написал Smooky
Re[4]: vector.erase
От: Кодт Россия  
Дата: 12.07.10 12:59
Оценка: +1
Здравствуйте, uzhas, Вы писали:

U>так можно делать только для ассоциативных контейнеров, но не для последовательных


Для списков тоже можно. Нельзя для сплошных или кусочно-сплошных — vector, deque, string.
Перекуём баги на фичи!
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.