std :: list <std :: shared_ptr> :: erase得到了一个SIGSEGV

时间:2018-03-15 04:22:43

标签: c++ list stl shared-ptr

请考虑以下代码:

#include <iostream>
#include <list>
#include <memory>

class Foo;

class Foo {
  public:
    Foo(int i): id(i) {}
    typename std::list<std::shared_ptr<Foo>>::iterator i2;
    int id;
};

int main() {
  std::list<std::shared_ptr<Foo>> l;
  auto f1 = std::make_shared<Foo>(1);
  f1->i2 = l.end();
  l.insert(f1->i2, f1);
  std::cout << f1->id << std::endl;
  std::cout << l.size() << std::endl;
  for (auto i: l) {
    std::cout << i->id << std::endl;
  }
  auto t = f1->i2;
  l.erase(t);
  std::cout << l.size() << std::endl;
}

执行这些代码将获得l.erase(t)的SIGSEGV,似乎ListNode在shared_ptr减少其ref_count之前被销毁。为什么?如何解决?

2 个答案:

答案 0 :(得分:1)

插入f1->i2l.end()后。您尝试删除l.end(),这是不允许的。

修复很简单。更改insert调用的行:

f1->i2 = l.insert(f1->i2, f1);

答案 1 :(得分:0)

在插入/删除操作之前初始化的迭代器在操作之后可能处于不确定状态,应该再次更新。您还试图通过迭代器删除列表中的节点,该迭代器本身指向list.end()。要删除列表的最后一个元素,您可以使用std::list.pop_back();

auto t = f1->i2;
l.erase(--t); // Change this in your code - decrease the iterator