从C++列表中删除项目

4
我试图从C++字符串列表中删除一些项目。代码编译成功,但在运行时出现“分段错误(core dumped)”错误。我已经将代码抽象如下。
#include <iostream>
#include <list>
using namespace std;

int main()
{
    //a string list
    list<string> entries;

    //add some entries into the list
    entries.push_back("one");
    entries.push_back("two");
    entries.push_back("three");
    entries.push_back("four");

    //pass over the list and delete a matched entry
    list<string>::iterator i = entries.begin();
    while(i != entries.end())
    {
        if(*i=="two")
            entries.erase(i);   // *** this line causes the error ***
        i++;
    }

    //print the result
    for(const string &entry : entries)
        cout<<entry<<"\n";
    return 0;
}

2
想一想当你从列表中删除迭代器i时会发生什么。在那之后,迭代器是否真的有效?我推荐使用erase参考,请注意它返回什么。 - Some programmer dude
1
erase returns the iterator. Do if() { i=erase} else {i++} - manuell
这个回答解决了你的问题吗?在遍历std::list时能否删除元素? - manuell
3个回答

5

std::list<T,Allocator>::erase 会使得指向被删除元素的迭代器i失效,即此后执行 i++ 等操作将导致未定义行为。

可以将其赋值给erase的返回值,该返回值是已删除元素之后的迭代器。

while(i != entries.end())
{
    if(*i=="two")
        i = entries.erase(i);
    else
        i++;
}

2

你可以直接“删除”该元素,无需使用迭代器,但如果你使用它,请注意erase会使迭代器失效。

#include <iostream>
#include <list>

int main ()
{
  //a string list
    std::list<std::string> entries;

    //add some entries into the list
    entries.push_back("one");
    entries.push_back("two");
    entries.push_back("three");
    entries.push_back("four");
    entries.push_back("two");

    entries.remove("two");
    std::cout<<entries.size() << std::endl;

  return 0;
}

1
已删除的迭代器将失效。为了方便起见,list::erase 返回已删除元素之后的下一个元素:
if(*i == "two") i = list.erase(i);
else ++i;

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接