在 std::list 上使用删除时的 C++ 分段

标签 c++ linked-list segmentation-fault erase

我正在尝试使用 erase 和列表迭代器从 C++ 链表中删除项目:

#include <iostream>
#include <string>
#include <list>

class Item
{
  public:
    Item() {}
    ~Item() {}
};

typedef std::list<Item> list_item_t;


int main(int argc, const char *argv[])
{

  // create a list and add items
  list_item_t newlist;
  for ( int i = 0 ; i < 10 ; ++i )
  {
    Item temp;
    newlist.push_back(temp);
    std::cout << "added item #" << i << std::endl;
  }

  // delete some items
  int count = 0;
  list_item_t::iterator it;

  for ( it = newlist.begin(); count < 5 ; ++it )
  {
    std::cout << "round #" << count << std::endl;
    newlist.erase( it );
    ++count;
  }
  return 0;
}

我得到了这个输出,但似乎无法追查原因:

added item #0
added item #1
added item #2
added item #3
added item #4
added item #5
added item #6
added item #7
added item #8
added item #9
round #0
round #1
Segmentation fault

我可能做错了,但无论如何都会感谢帮助。谢谢。

最佳答案

这里的核心问题是,在调用 erase 之后,您正在使用迭代器值 iterase 方法使迭代器无效,因此继续使用它会导致不良行为。相反,您想使用 erase 的返回值来获取删除值之后的下一个有效迭代器。

it = newList.begin();
for (int i = 0; i < 5; i++) {
  it = newList.erase(it);
}

包含对 newList.end() 的检查以解决 list 中没有至少 5 个元素的情况也没有坏处.

it = newList.begin();
for (int i = 0; i < 5 && it != newList.end(); i++) {
  it = newList.erase(it);
}

作为Tim指出,这里有一个很好的erase

引用

关于在 std::list 上使用删除时的 C++ 分段,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5145634/

相关文章:

c++ - SFINAE 将实例化类型限制为 std::chrono::duration 类型

c++ - 将派生类方法链接到基类方法

c++ - 如何修复此段错误?

java - 为什么 List<LinkedList<String>> 不起作用?

c++ - 为什么我在运行程序时收到错误 "segmentation fault"?

c++ - 时间不匹配

c++命名空间最佳实践困境

java - java中双链表删除节点

android - 如何找出Android中SIGSEGV的原因

我可以从 SIGSEGV 处理程序中终止另一个进程吗?