c++迭代器在迭代向量时崩溃

Posted

技术标签:

【中文标题】c++迭代器在迭代向量时崩溃【英文标题】:c++ Iterator crashing while iterating over vector 【发布时间】:2014-01-06 15:52:06 【问题描述】:

我有一个类Iformat,它有虚函数operator(),每个派生类都实现了这个函数。

class myClass

    std::vector<IFormat*> formatList_;
public:
  void formatAll()
  
    foreach(IFormat* format , formatList_)
    
        (*format)();
    
  

;

formatAll 函数在 myClass 的对象上调用,然后在循环中,operator() 函数正在删除这个 myClass 对象本身,该对象调用了导致崩溃的 formatAll() 函数迭代器正在损坏。

约束:不能声明operator() 定义否则返回错误类型。 此外,不能使用某些指标变量来跳出循环。

有人可以建议处理循环的方法,这样它就不会通过仅更改循环和迭代器并遵循约束来崩溃。 谢谢

【问题讨论】:

如果没有更多上下文,我认为我们无法解决这个问题。看起来你已经在某个地方搞砸了内存管理,但你本可以在任何地方搞砸。如果格式的 () 运算符正在删除父级,那么您显然没有很好地定义所有权... 最好的办法是用一个小例子来复制问题。从较大的程序中提取足够的内容来制作一个小示例,您可以发布该示例来演示该问题。通常,您会在处理该问题时自己发现问题。如果没有,那么您可以发布一个示例,其他人可以编译并帮助您调试。 你正在调试的testcase在哪里? 【参考方案1】:

是的,有时由于回调产生复杂的操作链,这个问题可能会浮出水面。

你有几个选择:

    formatAll 中复制formatList_ 并遍历该副本;您只是在复制指针,但如果容器很大,或者您在某个地方的紧密循环中运行它,这可能仍然是不可取的;

    在事件驱动的框架中,你可以推迟(*format)()的执行直到下一个应用程序“tick”开始,在这个循环中只将它添加到一些工作队列中;这实际上与选项 #1 相同,只是要复杂得多,但如果您确实拥有这样的框架,它可以非常好地插入;

    以某种方式确保回调不能直接或间接修改formatList_;您可以通过禁止“添加”或“删除”选项或强制那些被推迟来实现这一点。

“最干净”的方法是选项 #3,但同样,除非您处于事件驱动的框架中,否则实施起来可能很笨拙。

【讨论】:

以上是关于c++迭代器在迭代向量时崩溃的主要内容,如果未能解决你的问题,请参考以下文章

C++ 迭代器/向量在发布版本中不起作用

迭代器在添加到添加到列表向量的结构中时会停止指向某个值吗?

向量迭代器在赋值重载中不兼容

使用迭代器在向量中插入下一个值以映射

为啥在达到容量后在向量中进行插入时,C++ 不处理迭代器?

迭代器和向量的 Seg 错误