c++ - 列出超出范围的删除迭代器

标签 c++ iterator

我有以下代码:

static std::map<int,int> myFunction(std::list<int>& symbols){
    std::map<int,int> currCounts;
    std::map<int,int> payHits;
    for (std::list<int>::iterator l_itr = symbols.begin(); l_itr != symbols.end(); ++l_itr){
        myFunction_helper(*l_itr, l_itr, symbols, currCounts, payHits, 0);
    }
    return payHits;
}

static inline void myFunction_helper(int next, std::list<int>::iterator& pos, std::list<int> remainingSymbols, std::map<int,int> currCounts, std::map<int,int>& payHits, int i){
    currCounts[next] = currCounts.count(next) > 0 ? currCounts[next] + 1 : 1;
    remainingSymbols.erase(pos);
    if (i < numTiles && remainingSymbols.size() > 0){
        if (currCounts[next] == hitsNeeded[next]){
            int pay = symbolPays[next];
            payHits[pay] = payHits.count(pay) > 0 ? payHits[next] + 1 : 1;
        }
        else{
            for (std::list<int>::iterator l_itr = remainingSymbols.begin(); l_itr != remainingSymbols.end(); ++l_itr){
               myFunction_helper(*l_itr, l_itr, remainingSymbols, currCounts, payHits, i+1);
            }
        }
    }
    else{
        payHits[0] = payHits.count(0) > 0 ? payHits[0] + 1 : 1;
    }

}

它应该采用一组值并给出一些要求(numTiles (int)、hitsNeeded(符号图和需要选择它们才能获胜的次数))。我的代码基于 visual studio(最新版本)构建,但是当我尝试执行它时,第一次调用 myFunction_helper 时出现错误“列表删除迭代器超出范围”。我该如何避免这种情况?我特意按值传递了 remainingSymbols,这样我就可以在不影响其他递归堆栈框架成员的情况下修改它。我该如何解决这个问题,为什么会引发异常?


解决方案

从参数中删除迭代器。然后在迭代时使用以下代码片段:

int next = *l_itr;
l_itr = symbols.erase(l_itr);
myFunction_helper(next, remainingSymbols, currCounts, payHits, i+1);
symbols.push_front(next);

对于外部函数也是如此。将元素推到最前面不会破坏列表的迭代并允许我想要的东西(推到最前面在列表上也非常便宜)。

最佳答案

同意下面的评论。这是一个糟糕的答案,因为我们对业务案例的了解还不够多,无法提出一个好的解决方案。我在这里留下一个编辑过的版本,因为我刚刚恢复了被破坏的问题,它确实解释了尝试失败的原因。

为什么会引发异常

std::list<int> remainingSymbols是按值传递的,所以pos不再相关。引用来源list ,而不是 remainingSymbols 中源列表的拷贝.对一个 list 使用迭代器在另一个,即使是拷贝,也是致命的。

解决方案

常见的解决办法是解决办法是通过remainingSymbols通过引用:std::list<int> & remainingSymbols ,但由于这会中断回溯,因此您不能这样做。

相反,您必须为该位置传递一个不同的标识符,也许是索引。不幸的是,交互和重新迭代 list这是一项昂贵的任务,几乎总是超过 list 的快速插入和删除的好处。 .

关于c++ - 列出超出范围的删除迭代器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51052150/

相关文章:

c++ - 使用 msbuild 确保在 .NET 项目之前构建 C++ 项目

c++ - 迭代器的比较程度如何?

c++ - BidirectionalIterator 的 decltype(*it) 是什么?

c++ - boost::iterator_adaptor的遍历类别是由适配迭代器的类别决定的吗?

C++ STL : Duplicating code due to missing base-class for iterator and reverse_iterator

c++ - 迭代器的模板参数 : function infers type when called?

c++ - 在决定游戏中对象的生命时,何时使用指针、引用、原始指针和智能指针?

c++ - 检查类型是否在可变参数模板参数包中传递

c++ - 访问修饰符在继承中的不同行为取决于 "this"关键字和模板或缺少它们

javascript - 在 es6 中迭代对象并返回新对象