最近、次の関数のバグの修正を終えましたが、その答えに驚きました。私は次の関数を持っています(バグを見つける前のように書かれています):
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);
}
}
}
この関数Item
は、特定の位置を持つ「items」ベクトル内のすべてのオブジェクトを検索し、それらを「items」から削除して、「vect」に配置します。後で、という名前の関数putItemsAt
は反対のことを行い、アイテムを「アイテム」に追加します。初めて、正常にgetItemsAt
動作します。ただし、 afterputItemsAt
が呼び出されると、forループインgetItemsAt
は'items'の終わりから実行されます。'it'は無効なItem
ポインタを指し、getPosition()
segfaultsします。思い切って、に変更it!=items.end()
してit<items.end()
、うまくいきました。誰か教えてもらえますか?SOを見回すerase
と、イテレータを無効にする必要があるかもしれませんが、それでも、最初に機能する理由はわかりません。
リストの消去がより効率的であるため、「アイテム」をベクトルからリストに変更することを計画しているので、私も興味があります。リストには演算子!=
がないので、リストに使用する必要があることはわかっています。<
リストを使用して同じ問題が発生しますか?