std :: list迭代器奇怪的行为

时间:2014-08-09 15:21:31

标签: c++ multithreading visual-studio stl

2天了,我一直试图找出代码中的问题所在。我已经像这样隔离了这个问题:

有一个看起来像这样的循环:

int test_counter = 0; //Debug purpose only
for (const_iterator i = begin(); i != end(); i++, test_counter++){
    if ((*i)->isSoloed()) {
        soloed = (*i);
        break;
    }
}

该类的一个方法是继承std :: list。该列表包含指向某些类的动态分配实例的指针,但这可能不重要。

该列表恰好包含两个指针。

问题在于,在大约20%的运行中,第二次传递(test_counter == 1)在(* i) - > isSoloed()崩溃时发生访问冲突。在这种情况下,迭代器值为0xfeeefeee。 VisualStudio使用此精确值来指示已释放内存。从至少3个原因来看,这没有任何意义:

  1. 此处或其他线程中没有内存被处理
  2. 即使如此,迭代器将如何获得该值???
  3. 如果是的话 崩溃(异常窗口)我单击break并查看第二个 列表中的项目看起来完好无损,一切似乎都没问题。
  4. 请注意,这是一个多线程代码,这可能是这里的问题,但是循环是只读的(我甚至使用了const_iterator)而另一个具有指向此列表的指针的线程没有写入时间当循环运行时。但即便如此,如何影响迭代器的值,这是一个局部变量!

    非常感谢。

    //编辑: 我还注意到了两件有趣的事情:

    1)如果我在发生访问冲突后中断调试,我可以在循环之前返回(通过拖动下一个commant执行箭头)并再次运行它没有任何问题。所以这个问题很不幸是不确定的。

    2)我从来没有能够在发布版本中重现这个问题。

    方法的签名: MidiMessageSequence :: MidiEventHolder * getNextActiveEvent();

    并且它被调用如下: currentEvent = workingTrackList-> getNextActiveEvent();

    没什么特别的。该应用程序使用JUCE库,但这应该不是问题。我可以发布更多代码,告诉我应该发布什么。

2 个答案:

答案 0 :(得分:1)

两个可能的原因。 1:我指向的内存在被访问之前被删除(* i)。尝试添加检查是否(i)在访问i(* i) - > isSoloed()之前。 2:尝试在每次访问列表或列表项之前添加锁。

答案 1 :(得分:0)

我还没有发现问题究竟在哪里,但我取消了继承并改为使用了std :: list。有了它,TrackList类变成了std :: list的一种包装。我在访问列表的每个方法中放置了一个范围锁(在包装器中,因此从外部它的工作方式相同,我不需要关心从外部锁定),这几乎解决了这个问题。