迭代器有效性

Iterator validity

本文关键字:有效性 迭代器      更新时间:2023-10-16

我在这里寻找更深入的解释,而不仅仅是如何获取工作代码。我知道如何编写较短的代码以删除元素。我在此处编写了此测试代码,以查明删除时的故障点。似乎不仅i迭代器变得无效,而且是.end()迭代器...这很有趣。

为什么这有效?

    deque<shared_ptr<Vehicle>> data;
    data.push_back( shared_ptr<Vehicle>(new Vehicle("porsche")) );
    data.push_back( shared_ptr<Vehicle>(new Vehicle("fiat")) );
    data.push_back( shared_ptr<Vehicle>(new Vehicle("fiat")) );
    data.push_back( shared_ptr<Vehicle>(new Vehicle("bmw")) );
    data.push_back( shared_ptr<Vehicle>(new Vehicle("fiat")) );    
    auto end = data.end();
    for(auto i = data.begin(); i != end;)
    {
        if( (*i)->getName() == "fiat" )
        {
            auto ti = i;
            ++ti;
            end = data.end();   //above erase, works but not logical
            data.erase(i);
            i=ti;
        }
        else
        {
           ++i;
           end = data.end();
        }
    }

但这不起作用?

deque<shared_ptr<Vehicle>> data;
data.push_back( shared_ptr<Vehicle>(new Vehicle("porsche")) );
data.push_back( shared_ptr<Vehicle>(new Vehicle("fiat")) );
data.push_back( shared_ptr<Vehicle>(new Vehicle("fiat")) );
data.push_back( shared_ptr<Vehicle>(new Vehicle("bmw")) );
data.push_back( shared_ptr<Vehicle>(new Vehicle("fiat")) );    
auto end = data.end();
for(auto i = data.begin(); i != end;)
{
    if( (*i)->getName() == "fiat" )
    {
        auto ti = i;
        ++ti;
        data.erase(i);
        end = data.end();   //Bellow erase...more logical but crashes
        i=ti;
    }
    else
    {
       ++i;
       end = data.end();
    }
}

我猜想这里存在一些实现级别问题。也许是编译器错误。使用GCC 4.8.2。

您正在调用未定义的行为。从语言规范中,关于deque::erase

擦除的操作擦除了Deque的最后一个元素,仅使过去的末端无效 迭代器和所有迭代器以及对擦除元素的引用。擦除的擦除操作 Deque的第一个元素,但并非最后一个元素仅使迭代剂无效,并引用了擦除的元素 元素。擦除操作既不擦除第一个元素也不是Deque的最后一个元素 使过去的迭代器和所有迭代器无效,并引用了Deque的所有元素。

在您的情况下,您的end迭代器总是被凝结,这完全可以正常工作。第二种情况下的崩溃可能是由于i上的操作而不是data.end调用。