【发布时间】:2010-06-30 20:08:51
【问题描述】:
我最近修复了以下函数中的一个错误,答案让我感到惊讶。我有以下函数(在我发现错误之前写的):
void Level::getItemsAt(vector<item::Item>& vect, const Point& pt)
{
vector<itemPtr>::iterator it; // itemPtr is a typedef for a std::tr1::shared_ptr<item::Item>
for(it=items.begin(); it!=items.end(); ++it)
{
if((*it)->getPosition() == pt)
{
item::Item item(**it);
items.erase(it);
vect.push_back(item);
}
}
}
这个函数在“items”向量中找到所有Item对象,它们具有一定的位置,将它们从“items”中删除,并将它们放入“vect”中。后来,一个名为putItemsAt 的函数执行相反的操作,并将项目添加到“项目”。第一次通过,getItemsAt 工作正常。但是,在调用putItemsAt 之后,getItemsAt 中的 for 循环将在 'items' 的末尾运行。 'it' 将指向无效的Item 指针和getPosition() 段错误。凭直觉,我将it!=items.end() 更改为it<items.end(),并且成功了。谁能告诉我为什么?环顾 SO 表明它可能涉及 erase 使迭代器无效,但它仍然没有意义为什么它会在第一次通过。
我也很好奇,因为我计划将“项目”从向量更改为列表,因为列表的擦除更有效。我知道我必须使用!= 作为列表,因为它没有< 运算符。使用列表会遇到同样的问题吗?
【问题讨论】: