2015-10-13 99 views
2

我在多线程环境中遇到问题。我有一个正确的“Multiple Read-Single Write”锁定环境,修改了std::list。 我现在的问题是,我收到一封“列表迭代器不dereferencable” -exception和Visual只显示这一点,如果我检查它:std :: list容器填充错误的常见原因

data shows only (error) in visual debugger

在列表中的第一项的值为“0xcdcdcdcd” 。

可能是什么原因?我很乐意为您提供更多的细节,但我不知道从哪里开始,它已经耗费了几天的时间来调试它,但是如果代码以断点运行,则不会发生这种情况。

UPDATE

我有现在降低至一个更简单的问题(可惜仍然无法将其降低到一个小的非工作的例子)。它现在只能在单线程环境下运行 - 所以不能再应用多线程问题。

该列表中充满了5000个元素,我打电话给data.resize(100),它崩溃了 - 删除了3500个元素。 每个元素总是处理完全一样,它们全部包含在shared_ptr<>

我不保存任何迭代器,可能会失效,它只是通过删除列表中的随机元素而崩溃。 我不知道从哪里开始。

+2

“但如果代码与断点一起运行,则不会发生这种情况。”这表明一个竞争条件,使您的迭代器失效 – SingerOfTheFall

+0

底层容器是一个std :: list,它并不关心插入/删除时的迭代器失效(当然除去已删除的元素) - 但为什么调试器仍然显示已删除的元素? – EGOrecords

+0

http://en.wikipedia.org/wiki/Magic_number_(programming)建议0xCCCCCCCC:由微软的C++调试运行时库用来标记未初始化的堆栈内存 –

回答

1

我找到了答案:

破坏STL-Cotainers的常见原因是线程安全。

如果您正在同时修改容器,它可能会在随机地方破坏,如果您尝试遍历它,只会看到此破损。 在我的情况下,有一个并行的“push_front”操作,修改了容器,发生了典型的数据竞争。 看到这种行为的典型特征是当列表具有合理的大小时,但如果您在调试器中检查它,它将仅显示有用的值直到某个点,并且从那里仅有(error)

我设法通过在push_front周围添加一个写锁来解决它。

另一种情况我看到了这种行为,当我有一个堆栈溢出并摧毁了我的std :: list基地。根据被覆盖的字节数量,即使大小可能在一个合理的范围内,但是整个容器(不像上面所述的情况,其中第一个元素仍然是好的!)被损坏。

我希望有人做相同的编码,并错过了一个单一的锁必要性,并试图解决它作为一个堆栈问题会发现这有用!

2

您是否在容器内使用了std::auto_ptr

auto_ptr已在新版C++中弃用,因此只能谨慎使用。

auto_ptr不能很好地复制,所以它永远不应该被使用在容器中。

Why it is wrong to use std::auto_ptr<> with standard containers

使用std::shared_ptr或其它智能指针代替(从升压为例),如果C++ 11不可用。

+0

”谢谢你指出!我尝试了'std :: unique_ptr'和'std :: shared_ptr'。两者都给出相同的结果 - “(错误)” – EGOrecords

+0

你应该提供一个最简单的例子,然后...... – Nikko