【问题标题】:Segmentation fault in C++ programC++程序中的分段错误
【发布时间】:2012-10-12 21:46:12
【问题描述】:

我在我的链表实现中使用 STL 列表,但是当我在循环中使用擦除函数时,它会出现分段错误。有人能告诉我为什么会这样吗?

void remove(list<int> &myList,int N){
    int k = 1;
    list<int>::iterator it;
    for(it = myList.begin(); it != myList.end();it++){
        if(k == N){
            myList.erase(it);
            k = 1;
        }
        else
            k++;
    }
}

【问题讨论】:

  • 你能在调试器中运行它以找出导致问题的行以及它显示的错误吗?

标签: c++ stl segmentation-fault


【解决方案1】:

当您在迭代器上调用擦除时,它会使该迭代器无效。但是你继续使用它。您需要捕获擦除的返回值,并将其分配回您的迭代器,如下所示:

it = myList.erase(it);

但这将需要对您的循环进行轻微更改。如果你擦除,那么你不想增加,因为那样你将跳过一个元素。如果您最终擦除了最后一个元素,这尤其糟糕,因为您将越过 end 迭代器。所以,你应该只增加 if 你不擦除:

for(it = myList.begin(); it != myList.end(); ){
    if(k == N){
        it = myList.erase(it);
        k = 1;
    }
    else
    {
        k++;
        ++it;
    }
}

【讨论】:

    【解决方案2】:

    如果你删除一个元素,它的迭代器就会失效。换句话说,当您进行下一次迭代时,您将执行 it++ 不再有意义,因为 it 不再指向列表的元素。

    【讨论】:

      【解决方案3】:

      这样做,

      void remove(list<int> &myList,int N){
          int k = 1;
          list<int>::iterator it;
          for(it = myList.begin(); it != myList.end();){
              if(k == N){
                  myList.erase(it++);
                  k = 1;
              } else{
                  ++it;
                  k++;
              }
          }
      }
      

      当代码myList.erase(it++)被执行时,迭代器“it”所代表的对象无效。所以,未定义执行“it++”

      【讨论】:

        猜你喜欢
        • 2018-11-18
        • 2011-05-23
        • 1970-01-01
        • 2021-01-08
        • 1970-01-01
        • 2011-10-19
        • 2015-06-14
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多