请考虑以下代码:
#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之前被销毁。为什么?如何解决?
答案 0 :(得分:1)
插入f1->i2
左l.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