c++ - std::list 反向迭代和删除导致崩溃

标签 c++ list crash

我正在使用反向迭代器遍历 std::list 并使用插入它们时获得的正向迭代器从列表中删除一些元素。示例程序如下所示。我读到从列表中删除元素不会使其他迭代器无效,除了那些引用已删除元素的迭代器。但是没有提到 reverse_iterators,我的程序崩溃了。有人可以告诉我用法是否不正确吗?

程序正在做的是将一个元素添加到列表中,存储其迭代器,反向迭代列表并使用其存储的迭代器删除列表中的唯一元素。

输出粘贴在代码示例下方。

#include <list>
#include <iostream>
using namespace std;

struct node
{
    int data;
    list<node*>::iterator iter;
} a;

int main()
{
    list<node*> l;
    a.data = 1;
    l.push_front( &a );
    a.iter = l.begin();
    list<node*>::reverse_iterator ri = l.rbegin();
    while ( ri != l.rend() )
    {
        cout << (*ri)->data << endl;
        list<node*>::reverse_iterator rj = ri;
        ++ri;
        if ( ri ==  l.rend() )
            cout << "before erase: reached end" << endl;
        l.erase((*rj)->iter);
        if ( ri ==  l.rend() )
            cout << "after erase : reached end" << endl;
        else
            cout << "after erase : Not reached end" << endl;
    }
}

输出

1
before erase: reached end
after erase : Not reached end
610568524
before erase : reached end
Segmentation fault

最佳答案

在 VS2010 下,它会在第一次循环传递时在此处抛出异常:

 l.erase((*rj)->iter);
 if ( ri ==  l.rend() ) // exception

这应该让您大致了解发生了什么。你看,reverse_iterator 只是标准迭代器的包装器。也就是说,您应该记住它有返回底层迭代器的 base() 成员 - 您不必像在 node 结构中那样将它存储在其他地方。

Here's a great answer reverse_iteratoriterator 的关系。在您的情况下,rbegin 将基于 begin 迭代器。如果您从列表中删除 begin(您这样做了,因为它只有一个元素),所有基于此 iteratorreverse_iterator 都将变得无效。牢记这一点,您可以按以下方式重写循环:

while ( ri != l.rend() )
{  
    cout << (*ri)->data << endl;
    list<node*>::reverse_iterator rj = ri;
    ++ri;

    if ( ri ==  l.rend() )
        cout << "before erase: reached end" << endl;

    // the actual underlying iterator has an offset of one
    list<node*>::iterator it = l.erase(--rj.base());
    ri = reverse_iterator<list<node*>::iterator>(it);
    // or just
    // ri = reverse_iterator<list<node*>::iterator>(l.erase(--rj.base()));

    if ( ri ==  l.rend() )
        cout << "after erase : reached end" << endl;
    else
        cout << "after erase : Not reached end" << endl;
}

关于c++ - std::list 反向迭代和删除导致崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11339516/

相关文章:

c++ - 为什么我无法正确转换为 8UC3?

c++ - OpenCV中获取像素值

c++ - 需要帮助理解列表容器

c# - 如何将列表的内容放入单个 MessageBox 中?

iphone - 不规则地获取sqlite3_prepare_v2中的Exc_Bad_Access

c++ - 在 C++ 中,对应该具有相同内存布局的对象重新解释强制转换有多危险?

c++从 vector 中删除自定义对象:std::remove_if':找不到匹配的重载函数

python - Pyhonic 使用 if 语句来处理应用于分块列表的不等式

python - 为什么PyQt5 QPixmap使python崩溃?

c# - 在设计器中移动窗体上的控件时,Visual Studio 2012 突然崩溃