C++ 为什么我在这个迭代器中遇到分段错误?

C++ 为什么我在这个迭代器中遇到分段错误?,c++,pointers,iterator,segmentation-fault,adjacency-list,C++,Pointers,Iterator,Segmentation Fault,Adjacency List,我正在编写一个程序,它应该浏览一个图,并计算出需要删除的边的最小数量,以留下一个每个连接组都有偶数个顶点的森林。我知道如何解决这个问题,但是当我尝试遍历一个列表时,我发现了一个分段错误,并且不知道为什么 #include <cmath> #include <cstdio> #include <list> #include <vector> #include <iostream> #include <algorithm> us

我正在编写一个程序,它应该浏览一个图,并计算出需要删除的边的最小数量,以留下一个每个连接组都有偶数个顶点的森林。我知道如何解决这个问题,但是当我尝试遍历一个列表时,我发现了一个分段错误,并且不知道为什么

#include <cmath>
#include <cstdio>
#include <list>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;

int main() {
    /* Enter your code here. Read input from STDIN. Print output to STDOUT */

    int N;
    cin >> N;
    int M; 
    cin >> M;

    // matrix of adjacency list to hold node values
    vector<list<int> > adjList(N, list<int>());

    // find the number of children nodes each node has
    int ui, vi;
    for (int i = 0; i < M; i++) {
      cin >> ui;
      cin >> vi;
      ui--;
      vi--;
      //cout << ui << " " << vi << endl;
      adjList[ui].push_back(vi);
      adjList[vi].push_back(ui);
      //cout << "list length: " << adjList[ui].size() << endl;
    }
    //cout << "after for loop" << endl;
    // count the number of nodes with even numbers of children

    for (int i = 0; i <= M; i++) {
      cout << i << "-> ";
      for (list<int>::iterator it = adjList[i].begin(); it != adjList[i].end(); it++) {
        cout << *it << " ";
      }
      cout << endl;
    }

    int edgesRemoved = 0;

    for (int i = 0; i <= M; i++) {
      for (list<int>::iterator it = adjList[i].begin(); it != adjList[i].end(); ++it) {
        int j = *it;
        if (adjList[j].size() % 2 == 1) {
          // delete vertex from current list
          cout << "test" << endl;
          adjList[i].erase(it);

          // delete vertex on the other list
          cout << "test" << endl;
          cout << j << endl;
          cout << *adjList[j].begin() << endl;
          for (list<int>::iterator it2 = adjList[j].begin(); it2 != adjList[j].end(); ++it2) {
            cout << *it2 << " ";
            if (i == *it2) {
              adjList[j].erase(it2);
            }
          }

          edgesRemoved++;
        }
      }
    }
    cout << edgesRemoved << endl;
    return 0;
}

在对列表进行迭代时,不能删除列表中的当前项(迭代器指向的对象)。你可以这样做:

adjList[j].erase(it2++);

但是,在进行迭代时,最好不要收缩或扩展列表。

在对列表进行迭代时,不能删除列表中的当前项(迭代器指向的对象)。你可以这样做:

adjList[j].erase(it2++);

然而,在进行迭代时,最好不要收缩或扩展列表。

删除迭代器下的项会使迭代器无效;使用它会进一步导致未定义的行为,因此任何事情都可能发生。这类事情的惯用说法是:

std::list<int>::iterator it = adjList[i].begin();
while ( it != adjList[i].end() ) {
    if ( *it == i ) {
        it = adjList[j].erase( it );
    } else {
        ++ it;
    }
}
std::list::iterator it=adjList[i].begin();
while(it!=adjList[i].end()){
如果(*it==i){
它=调整列表[j]。擦除(它);
}否则{
++它;
}
}
erase
函数将迭代器返回到被删除元素之后的元素


这对所有序列类型都有效,不仅仅是
std::list

删除迭代器下的项会使迭代器无效;使用它会进一步导致未定义的行为,因此任何事情都可能发生。这类事情的惯用说法是:

std::list<int>::iterator it = adjList[i].begin();
while ( it != adjList[i].end() ) {
    if ( *it == i ) {
        it = adjList[j].erase( it );
    } else {
        ++ it;
    }
}
std::list::iterator it=adjList[i].begin();
while(it!=adjList[i].end()){
如果(*it==i){
它=调整列表[j]。擦除(它);
}否则{
++它;
}
}
erase
函数将迭代器返回到被删除元素之后的元素


这对所有序列类型都有效,不仅仅是
std::list

请发布一个可能是您现在使用真正的调试器的时候了,而不是
cout
。请发布一个可能是您现在使用真正的调试器的时候了,因此,在这种情况下,如何删除列表中不在开头或结尾的特定元素?或者在这种情况下使用邻接矩阵是一个更好的主意吗?我在答案中包含的代码可以做到这一点。您可以在迭代器上使用后期修复增量进行删除。使用
std::list
的全部目的是能够在任意点进行删除和插入,即在对其进行迭代时。因此,在这种情况下,如何删除列表中不在开头或结尾的特定元素?或者在这种情况下使用邻接矩阵是一个更好的主意吗?我在答案中包含的代码可以做到这一点。您可以在迭代器上使用后期修复增量进行删除。使用
std::list
的全部目的是能够在任意点进行删除和插入,即在对其进行迭代时。