【问题标题】:using iterator for vectors in a list对列表中的向量使用迭代器
【发布时间】:2017-08-14 03:51:51
【问题描述】:

我正在尝试在列表中使用迭代器,如下所示,这是正确的方法吗?

我有两个向量 v1 和 v2,我正在使用两个迭代器 it1 和 it2。后来,我使用list<vector<int>::iterator> 的列表来push_back 迭代器it1 和it2。这可行,但如果任何一个向量为空,它就会崩溃。

int main() {
vector<int> v1 ={1,2,3};
vector<int> v2 ={4,5,6,7};

vector<int>::iterator it1 = v1.begin();
vector<int>::iterator it2 = v2.begin();


list<vector<int>::iterator> l;
l.push_back(it1);
l.push_back(it2);

for(auto a : l){
    vector<int>::iterator it = a;
    while(*it){
        cout<<*it<<endl;
        it++;
    }
}
    return 0;
}

【问题讨论】:

  • 这太疯狂了。为什么是迭代器向量,如果向量发生突变,它们会失效?此外,您没有捕获结束迭代器。这就是你应该知道你在向量末尾的方式,而不是*it。如果列表为空 begin == end 并且您没有迭代,也不需要取消引用 it

标签: c++


【解决方案1】:

崩溃来自于尝试取消引用 while(*it){ 行中的 while(*it){。如果向量v 为空,则迭代器v.begin() 不会指向有效内存,取消引用会导致分段错误。

【讨论】:

  • 这就是为什么你总是在对迭代器或任何指针做任何事情之前检查。在你的 while 循环之前,只需简单地添加 if(*it) { while(*it) cout
  • @OmidCompSCI 我不认为这会有所帮助。if(*it) 也在取消引用并将失败。
  • @OmidCompSCI 不要认为这会起作用,Segmentation Fault 仍然会发生。
  • 当然它的解引用失败了。你需要结束迭代器才能让它工作。
  • @PaulRooney 如果他只是使用for循环并且终止条件是它,则不会发生seg错误!=it.end(),然后您可以添加检查我有if(*it) { //你需要什么 }
【解决方案2】:

它会失败,因为在您知道它可以取消引用之前,您无法取消引用迭代器。如果向量是空的 begin == end 并且 end 不是一个有效的取消引用的东西,因为它是容器末尾的一个。

您将无法在不知道 end 的情况下迭代您的容器,并且您不会捕获它,您只能捕获 begin。简单地取消引用迭代器来测试有效性是不正确的。它可以保存任何值。

为每个向量捕获一对迭代器的替代方案怎么样?

#include <vector>
#include <list>

#include <iostream>
#include <utility>
using namespace std;

int main() 
{
    const vector<int> v1 ={1,2,3};
    const vector<int> v2 ={4,5,6,7};

    list<pair<vector<int>::const_iterator, 
              vector<int>::const_iterator>> L;

    L.push_back(make_pair(begin(v1), end(v1)));
    L.push_back(make_pair(begin(v2), end(v2)));

    for(const auto& a : L){

        for(auto it = a.first; it != a.second; ++it)
        {
            cout << *it << '\n';
        }
    }
}

现在您也可以停止,因为您也知道结束迭代器。

【讨论】:

    【解决方案3】:
    list<vector<int>::iterator> l;
    l.push_back(it1);
    

    如果假设v1 是空的,那么it1 将是v1::end(),它是向量的最后一个元素并且不是向量的一部分。所以稍后当你这样做时

    while(*it){
    

    您正在尝试取消对 v::end() 的引用,这是导致崩溃的原因。为避免这种情况,您应仅在迭代器未指向 end 时插入 l

    if(it1!= v1.end())
       l.push_back(it1);
    

    【讨论】:

      猜你喜欢
      • 2013-02-07
      • 1970-01-01
      • 2017-08-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多