簡體   English   中英

在std :: list上使用擦除時的C ++分段

[英]C++ Segmentation when using erase on std::list

我正在嘗試使用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;
}

我得到此輸出,似乎無法跟蹤原因:

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

我可能做錯了,但是無論如何,我們將不勝感激。 謝謝。

這里的核心問題是,你正在使用的迭代器值, it ,你叫后erase就可以了。 erase方法會使迭代器無效,因此繼續使用它會導致不良行為。 相反,您想使用erase的返回值來獲取擦除值之后的下一個有效迭代器。

it = newList.begin();
for (int i = 0; i < 5; i++) {
  it = newList.erase(it);
}

包括檢查newList.end()來解決list中至少包含5個元素的情況也沒有什么壞處。

it = newList.begin();
for (int i = 0; i < 5 && it != newList.end(); i++) {
  it = newList.erase(it);
}

正如Tim所指出的,這是erase的絕佳參考

當您在位置刪除元素it ,迭代器it變得無效-它指向一塊內存,你剛剛釋放。

erase(it)函數返回另一個迭代器,該迭代器指向列表的下一個元素。 用那個!

我這樣做:

for(list<type>::iterator i = list.begin(); i != list.end(); i++)
{
     if(shouldErase)
     { 
        i = list.erase(i);
        i--;
     }
}

已編輯,因為我是一個看不懂大聲笑的笨蛋。

當您在循環中erase()時,您使迭代器無效。 做這樣的事情來代替擦除循環會更簡單:

list_item_t::iterator endIter = newlist.begin();
std::advance(endIter, 5);
newList.erase(newlist.begin(), endIter);

您可能也對“ 擦除刪除”這一慣用語感興趣。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM