2014-08-29 2 views
0

Несмотря на то, что я посмотрел на эту страницу: http://www.cplusplus.com/reference/vector/vector/erase/, Я до сих пор не понимаю, почему у меня возникает ошибка времени выполнения VS2010 («векторный итератор не увеличивается») при выполнении последней строки следующий код:недействительный итератор после стирания вектора STL

vector<int> vec; 
for(int i = 0 ; i < 10 ; i++) 
    vec.push_back(i); 
auto itb = vec.begin()+1; // 2nd item of the vector 
auto it = itb + 2;  // 4th item of the vector 
it = vec.erase(itb, it); // remove the 2nd & 3rd 
++it; // Error happens when trying to execute this line 

Я думал стирание бы вернуть итератор на элемент, который является лишь после того, как последний удален один. Итак, здесь он будет указывать на элемент со значением 3. Здесь, поскольку вектор достаточно длинный, стирает не возвращает vec.end(). Оттуда я должен иметь возможность выполнять итерацию с допустимым итератором. Но нет! Почему?

Принимая во внимание, что код работает:

vector<int> vec; 
for(int i = 0 ; i < 10 ; i++) 
    vec.push_back(i); 
auto itb = vec.begin()+1; 
auto it = itb + 2; 
vec.erase(itb, it); 
it = vec.begin()+1; // re-generate an iterator from the begin() one. 
++it; 

Edit: Если я немного изменить код из «Влада из Москвы» (см ниже) в пустой файл main.cpp, то я все еще имею проблема. Итак, я думаю, у меня проблема с компилятором.

Вот код:

#include <iostream> 
#include <vector> 
int main() 
{ 
    std::vector<int> v; 
    for (int i = 0; i < 10; i++) v.push_back(i); 

    for (auto it = v.begin(); it != v.end() ; ++it) std::cout << *it << ' '; 
    std::cout << std::endl; 

    auto itb = v.begin() + 1; 
    auto it = itb + 2; 

    it = v.erase(itb, it); 

    ++it; // Crash here 

    for (auto it = v.begin(); it != v.end() ; ++it) std::cout << *it << ' '; 
    std::cout << std::endl; 

    while (it != v.end()) std::cout << *it++ << ' '; 
std::cout << std::endl; 

    return 0; 
} 

Позвольте мне описать мой конфиг: Я бегу 64bit Win7 Окончательный под Parallel рабочий стол (Mac), с VC++ 6, VCS2003, VS2005, VS2008, VS2010 (без SP, .NET Framework 4.5).

+0

Помните, что ваш цикл может быть просто вызовом 'std :: iota'. – chris

+4

Нет ничего плохого в этом коде. Вы уверены, что это тот, с которым вы работаете? – jrok

+0

Если программа выйдет из строя на этой строке с помощью вышеприведенного фрагмента, вы, вероятно, имеете неопределенное поведение в другом месте, которое искажает память. – user2079303

ответ

1

Этот пример показывает, что нет ничего плохого в первом фрагменте кода

#include <iostream> 
#include <vector> 


int main() 
{ 
    std::vector<int> v; 
    for (int i = 0; i < 10; i++) v.push_back(i); 

    for (int x : v) std::cout << x << ' '; 
    std::cout << std::endl; 

    auto itb = v.begin() + 1; 
    auto it = itb + 2; 

    it = v.erase(itb, it); 

    ++it; 

    for (int x : v) std::cout << x << ' '; 
    std::cout << std::endl; 

    while (it != v.end()) std::cout << *it++ << ' '; 
    std::cout << std::endl; 

    return 0; 
} 

Выход

0 1 2 3 4 5 6 7 8 9 
0 3 4 5 6 7 8 9 
4 5 6 7 8 9 

Если удалить заявление

++it; 

, то выход будет

0 1 2 3 4 5 6 7 8 9 
0 3 4 5 6 7 8 9 
3 4 5 6 7 8 9 

EDIT: Вот та же программа работает в MS VC++ 2010

#include "stdafx.h" 
#include <iostream> 
#include <vector> 

int _tmain(int argc, _TCHAR* argv[]) 
{ 
    std::vector<int> v; 
    for (int i = 0; i < 10; i++) v.push_back(i); 

    for each (int x in v) std::cout << x << ' '; 
    std::cout << std::endl; 

    auto itb = v.begin() + 1; 
    auto it = itb + 2; 

    it = v.erase(itb, it); 

    ++it; 

    for each (int x in v) std::cout << x << ' '; 
    std::cout << std::endl; 

    while (it != v.end()) std::cout << *it++ << ' '; 
    std::cout << std::endl; 
} 

Я надеюсь, что эти примеры помогут вам найти вашу реальную ошибку.

+0

Я предполагаю, что у меня проблема с компилятором, потому что я попробовал ваш верхний код (слегка модифицированный, чтобы не использовать «автоматический цикл» для печати), и у меня все еще такая же проблема. – OhMyCode

+0

@OhMyCode В моем сообщении есть пример, запущенный в MS VS 2010. Так что, возможно, причина в ваших модификациях. Другая причина может заключаться в том, что компилятор использует неправильный заголовок. –

+0

да, но я ленился, чтобы воссоздать проект.Итак, я просто #if 0/# endif мой код и поместил ваш первый (поскольку я всегда отключил материал stdafx.h, потому что мой код должен быть портативным). В противном случае «вектор». файл, с которого он падает, находится в «C: \ Program Files (x86) \ Microsoft Visual Studio 10.0 \ VC \ include». – OhMyCode