矢量擦除迭代器超出范围[关闭]

Posted

技术标签:

【中文标题】矢量擦除迭代器超出范围[关闭]【英文标题】:Vector erase iterator outside range [closed] 【发布时间】:2015-01-30 23:45:11 【问题描述】:

使用 C++ 将我的游戏引擎中的一些代码从 Mac 移植到 Windows,我收到此运行时错误:“矢量擦除超出范围”。它适用于 Mac!

void Entity::runDeferreds() 
    for (auto it = deferreds.begin(); it != deferreds.end(); /* nothing */ ) 
        if (it->Condition()) 
            it->Execution();

            it = deferreds.erase(it);
         else 
            ++it;
        
    

这会遍历“延迟”任务列表,这些任务存储在名为 deferredsstd::vector<DeferredCall> 中。如果DeferredCallCondition() 被满足,那么它的Execution() 被运行,它应该从vector 中被移除。但是,相反,我得到了上述错误!

DeferredCall 看起来是这样的,并不是说它太重要了:

struct DeferredCall 
    std::function<bool()> Condition;
    std::function<void()> Execution;
;

帮忙?!

编辑:- 替代方法

我也试过这个,再次在 Mac 上工作:

deferreds.erase(std::remove_if(deferreds.begin(), deferreds.end(),
    [](DeferredCall &call) 
            if (call.Condition()) 
                call.Execution();
                return true;
            

            return false;
        
    ), deferreds.end());

但是,在这种情况下,我得到“向量迭代器不兼容”。

【问题讨论】:

你不应该在擦除(它)之后跳出循环吗?否则,您将再次迭代相同的已擦除迭代器。 回调是否可以(甚至间接)访问deferreds。可以在回调中修改吗? @DanSimmons: std::vector::erase 在此代码分配给it 的已移除元素之后返回一个迭代器。这段代码看起来正确地实现了一个常见的习惯用法。 这两个看起来都不错。这是您的实际代码还是只是一个示例?我问的原因是,大多数情况下,当您看到“迭代器不兼容”消息时,这是因为向量是按值返回的,而不是从 get 函数中引用。 ***.com/help/mcve 【参考方案1】:

虽然它没有回答你的错误来自哪里,但你可以尝试重新编写代码,如下所示:

const auto pred = [](Deferred& d) return !d.Condition(); ;
auto itMatch = std::partition( defs.begin(), defs.end(), pred);

const auto action = [](Deferred& d) d.Execution(); ;
std::for_each(itMatch, defs.end(), action);

defs.erase(itMatch, defs.end());

另外,std::vector::erase 保证返回完全有效的迭代器。不过可能是vector::end()

链接:std::partition、std::for_each、std::vector::erase

【讨论】:

好主意。这避免了在传递给std::remove_if的谓词中的对象上调用非常量函数的未定义行为@

以上是关于矢量擦除迭代器超出范围[关闭]的主要内容,如果未能解决你的问题,请参考以下文章

c++ 断言字符串迭代器偏移超出范围

如何使用 mpi scatter 修复“矢量下标超出范围”?

向量迭代器 + 偏移超出范围

C ++ - 向量迭代器+偏移超出范围

需要有关矢量超出范围错误的帮助

矢量下标超出范围错误消息 3