[英]C++ Segmentation when using erase on std::list
I'm trying to remove items from a C++ linked list using erase
and a list iterator: 我正在尝试使用
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;
}
I get this output and can't seem to trace the reason: 我得到此输出,似乎无法跟踪原因:
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
I'm probably doing it wrong, but would appreciate help anyway. 我可能做错了,但是无论如何,我们将不胜感激。 thanks.
谢谢。
The core problem here is you're using at iterator value, it
, after you've called erase
on it. 这里的核心问题是,你正在使用的迭代器值,
it
,你叫后erase
就可以了。 The erase
method invalidates the iterator and hence continuing to use it results in bad behavior. erase
方法会使迭代器无效,因此继续使用它会导致不良行为。 Instead you want to use the return of erase
to get the next valid iterator after the erased value. 相反,您想使用
erase
的返回值来获取擦除值之后的下一个有效迭代器。
it = newList.begin();
for (int i = 0; i < 5; i++) {
it = newList.erase(it);
}
It also doesn't hurt to include a check for newList.end()
to account for the case where there aren't at least 5 elements in the list
. 包括检查
newList.end()
来解决list
中至少包含5个元素的情况也没有什么坏处。
it = newList.begin();
for (int i = 0; i < 5 && it != newList.end(); i++) {
it = newList.erase(it);
}
As Tim pointed out, here's a great reference for erase
正如Tim所指出的,这是
erase
的绝佳参考
When you erase an element at position it
, the iterator it
gets invalidated - it points to a piece of memory that you just freed. 当您在位置删除元素
it
,迭代器it
变得无效-它指向一块内存,你刚刚释放。
The erase(it)
function returns another iterator pointing to the next element to the list. erase(it)
函数返回另一个迭代器,该迭代器指向列表的下一个元素。 Use that one! 用那个!
I do this: 我这样做:
for(list<type>::iterator i = list.begin(); i != list.end(); i++)
{
if(shouldErase)
{
i = list.erase(i);
i--;
}
}
Edited because I'm a bonehead that can't read apparently lol. 已编辑,因为我是一个看不懂大声笑的笨蛋。
You're invalidating your iterator when you erase()
within the loop. 当您在循环中
erase()
时,您使迭代器无效。 It would be simpler to do something like this in place of your erase loop: 做这样的事情来代替擦除循环会更简单:
list_item_t::iterator endIter = newlist.begin();
std::advance(endIter, 5);
newList.erase(newlist.begin(), endIter);
You might also be interested in the erase-remove idiom . 您可能也对“ 擦除删除”这一惯用语感兴趣。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.