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个原因来看,这没有任何意义:
请注意,这是一个多线程代码,这可能是这里的问题,但是循环是只读的(我甚至使用了const_iterator)而另一个具有指向此列表的指针的线程没有写入时间当循环运行时。但即便如此,如何影响迭代器的值,这是一个局部变量!
非常感谢。
//编辑: 我还注意到了两件有趣的事情:
1)如果我在发生访问冲突后中断调试,我可以在循环之前返回(通过拖动下一个commant执行箭头)并再次运行它没有任何问题。所以这个问题很不幸是不确定的。
2)我从来没有能够在发布版本中重现这个问题。
方法的签名: MidiMessageSequence :: MidiEventHolder * getNextActiveEvent();
并且它被调用如下: currentEvent = workingTrackList-> getNextActiveEvent();
没什么特别的。该应用程序使用JUCE库,但这应该不是问题。我可以发布更多代码,告诉我应该发布什么。
答案 0 :(得分:1)
两个可能的原因。 1:我指向的内存在被访问之前被删除(* i)。尝试添加检查是否(i)在访问i(* i) - > isSoloed()之前。 2:尝试在每次访问列表或列表项之前添加锁。
答案 1 :(得分:0)
我还没有发现问题究竟在哪里,但我取消了继承并改为使用了std :: list。有了它,TrackList类变成了std :: list的一种包装。我在访问列表的每个方法中放置了一个范围锁(在包装器中,因此从外部它的工作方式相同,我不需要关心从外部锁定),这几乎解决了这个问题。