有人可以解释为什么以下程序崩溃了吗?

时间:2014-06-09 16:30:09

标签: c++

#include <vector>
#include <iostream>

using namespace std;

简单的矢量推送操作

int main() {
  vector<int> v;
  v.push_back(1);
  v.push_back(2);
  v.push_back(3);
  v.push_back(4);
  for (vector<int>::iterator i = v.begin();
       i != v.end(); i++) {
    cout << *i << endl;

我无法理解下面这点发生了什么

    if (*i == 1) {
      v.push_back(5);
    }
  }
}

3 个答案:

答案 0 :(得分:13)

push_back()使您的迭代器失效。像你这样在循环中使用它是一个错误,因为iv之后不需要与push_back()有任何关系。

答案 1 :(得分:2)

错误的原因如另一个答案中所述。如果你真的想push_back(5)为向量中的每个项目等于1,那么下面的代码就可以了:

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

    using namespace std;
    int main() 
    {
       vector<int> v;
       v.push_back(1);
       v.push_back(2);
       v.push_back(3);
       v.push_back(4);
       v.push_back(1);
       v.resize(v.size() + std::count(v.begin(), v.end(), 1), 5);
       std::copy(v.begin(), v.end(), std::ostream_iterator<int>(cout, " "));
    }

输出:

1 2 3 4 1 5 5

基本上,所有这些都是使用resize() vector成员在一行代码中完成的。 std::count计算向量中的条目数等于1.然后调整原始向量的大小,并将新元素设置为5.

答案 2 :(得分:0)

<强>分析:
如果新的矢量大小超过其容量,v.push_back(5) 可能重新分配存储位置(请参阅http://www.cplusplus.com/reference/vector/vector/push_back/)。 如果这种情况发生,所有迭代器都会失效。这会导致您的异常。

3解决方案:

(1)如果你不需要继续迭代(即你必须在第一次出现后添加一个项目),那么你可以在条件pushback()之后添加break;以便中断循环。你的程序的其余部分将运行而不会崩溃。

(2)如果您事先知道可能需要推迟AT MAXIMUM个元素,那么您可以在迭代之前使用v.reserve(v.capacity()+n);

提前增加向量容量

(3)最后一种可能性,如果你在黑暗中关于潜在的插入,那么你应该在插入之前检查迭代器位置,然后在插入之后重新循环到那个位置。这是按照比例的性能成本完成的,但它确实有效。 if子句看起来像:

if (*i == 1) {
    cout << "op..."; 
    int j=i-v.begin(); 
    v.push_back(5);
    cout<<"Break the iteration at position " << j <<endl; 
    i=v.begin(); 
    for (++j; j; j--) 
        i++;
    }

我已经使用VC 2013测试了所有这三种解决方案,但它们似乎都有效。