2016-04-30 90 views
0

在下面的代码中,如果我尝试删除除最后一个元素之外的任何元素,代码将正常工作。但是,如果我尝试删除最后一个元素,则会引发运行时错误。不知道为什么?在删除循环中向量的最后一个元素时的问题

#include <iostream> 
#include <string> 
#include <vector> 
using namespace std; 
int main() 
{ 
    vector<string> s; 
    s.push_back("Jacob"); 
    s.push_back("Jamal"); 
    s.push_back("Joseph"); 
    s.push_back("Janardan"); 
    vector<string>::iterator it; 

    for(it = s.begin(); it != s.end() ; it++) 
     cout<<*it<<endl; 

    for(it = s.begin(); it != s.end() ; it++) 
     if(*it == "Janardan") 
      s.erase(it); 

    for(it = s.begin(); it != s.end() ; it++) 
     cout<<*it<<endl; 

    return 0; 
} 

回答

1

它抛出一个运行时错误的原因是因为你试图通过调用it++你删除了最后一个元素之后递增迭代器。这会导致迭代器超出范围。一个更好的办法来解决,这将是:

for(it = s.begin(); it != s.end();) { 
    if(*it == "Janardan") { 
     it = s.erase(it); 
    } else { 
     it++; 
    } 
} 
1

里有你的std::vector 4个元素,所以循环将执行4次。

问题是,当删除一个元素时,之后的所有迭代器删除的元素不再有效。这包括it,它指向一个不再存在的元素,所以它会抛出。


解决方法有很多,你可以使用

  • 如果std::vector没有任何重复,你可以break擦除元素

  • 使用std::remove_if

像这样

std::remove_if(std::begin(s), std::end(s), [](const auto& value) { 
    return value == "Janardan"; 
}); 
  • 使用std::find

像这样

auto iterator = std::begin(s); //Initialize iterator to the first element 

//std::find returns std::end(s) if it didn't find anything 
if ((iterator = std::find(std::begin(s), std::end(s), "Janardan")) != std::end(s)) 
    s.erase(iterator); //Erase element 
相关问题