如何逐个擦除STL双端的所有元素?

时间:2013-04-18 23:22:12

标签: c++ stl iterator

我正面临一个奇怪的问题,即在迭代它时擦除STL列表中的元素。我知道擦除元素会使迭代器无效。所以,要么

"testQueue.erase(it++);""it = testQueue.erase(it);"

应该使用。

为了简化我的问题,我尝试在迭代列表时删除所有元素。但是,当使用前一种机制时,我会收到Segfault。

以下是完整代码供您参考。

#include <iostream>
#include <queue>
#include <string>

int main()
{
    std::string d1 = "d1";
    std::string d2 = "d2";
    std::string d3 = "d3";

    std::deque<std::string> testQueue;
    testQueue.push_back(d1);
    testQueue.push_back(d2);
    testQueue.push_back(d3);

    std::deque<std::string>::iterator it = testQueue.begin();
    for(; it!=testQueue.end(); ++it){
        std::cout << (*it) << std::endl;
    }

    std::cout << "========" << std::endl;

    it = testQueue.begin();
    while(it!=testQueue.end()){
        testQueue.erase(it++); // This causes Segfault
        //it = testQueue.erase(it); // This one works just fine.
    }
    std::cout << "========" << std::endl;
    std::cout << "========" << std::endl;
    std::cout << "========" << std::endl;
    std::cout << "========" << std::endl;
    std::cout << "========" << std::endl;

    it = testQueue.begin();
    for(; it!=testQueue.end(); ++it){
        std::cout << (*it) << std::endl;
    }


    return 0;
}

我对后增量方法不起作用的原因一无所知。请注意,最终目标不是使用此方法来擦除所有元素。但是,我想了解我提到的两种方法的区别。

5 个答案:

答案 0 :(得分:5)

迭代器失效规则对于不同的容器是不同的。

std::deque::erase

  

所有迭代器和引用都是无效的,除非擦除的成员位于双端队列的末尾(前面或后面)(在这种情况下,只有迭代器和对擦除成员的引用无效)[23.2 .1.3 / 4]

您从testQueue.erase(it++)收到段错误,因为it++生成的迭代器已失效。

答案 1 :(得分:1)

因为迭代器(以及该问题的所有引用)从std::deque变为无效after erasing元素。你应该使用:

while(it!=testQueue.end()){
    it = testQueue.erase(it);
}

答案 2 :(得分:1)

std::deque::erase擦除迭代器指向的元素,并返回一个指向删除后的元素的迭代器。它也使给定的迭代器无效,因此您只需将其指定为“继续”。

这就是为什么这样做的原因:

while(it!=testQueue.end()){
    it = testQueue.erase(it);
}

但是如果你对迭代器进行后递增并将其传递给erase,那么元素将被删除,之后(旧)迭代器被复制并递增。由于旧的迭代器变得无效,增量的迭代器也是如此。

要清除整个双端队列(您似乎想要这样做),还有clear()

答案 3 :(得分:1)

既然你总是只是擦除第一个元素,为什么不让生活变得更简单:

while (!your_list.empty())
    your_list.erase(your_list.begin());

答案 4 :(得分:0)

testQueue.erase(it++);

这等于这个

testQueue.erase(it);

it++;

但“它”指向什么都没有,因为它被删除而且无法增加。