0

我面临一个与在迭代 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;
}

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

4

5 回答 5

6

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

对于std::deque::erase

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

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

于 2013-04-18T23:28:30.130 回答
1

因为std::deque. _ 你应该使用:

while(it!=testQueue.end()){
    it = testQueue.erase(it);
}
于 2013-04-18T23:26:25.493 回答
1

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

这就是为什么它有效:

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

但是,如果您对迭代器进行后递增并将其传递给擦除,则元素将被擦除,然后(旧)迭代器被复制并递增。由于旧的迭代器变得无效,因此增加的迭代器也是如此。

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

于 2013-04-18T23:27:55.577 回答
1

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

while (!your_list.empty())
    your_list.erase(your_list.begin());
于 2013-04-18T23:30:45.773 回答
0

testQueue.erase(it++);

这等于这个

testQueue.erase(it);

it++;

但是“it”什么都没有,因为它被删除了,不能增加。

于 2013-04-18T23:34:49.323 回答