我在多线程环境中遇到了麻烦。我有一个正确的"多读 - 单写" -Lock设置环境,它修改std::list
。
我现在的问题是,我收到一个"列表迭代器而不是dereferencable" -exception并且Visual只在我检查时显示它:
列表中的第一项具有值" 0xcdcdcdcd"。
可能是什么原因?我很乐意为您提供更多详细信息,但我不知道从哪里开始,它已经花了我几天调试它,但如果代码运行断点,这不会发生。
更新
到目前为止,我已将它简化为一个更简单的问题(遗憾的是仍然无法将其简化为一个小的非工作示例)。它现在只在单线程环境中运行 - 因此不再适用多线程问题。
列表中填充了aroud 5000个元素,我打电话给data.resize(100)
并且它崩溃了 - 删除了~3500个元素。
每个元素的处理方式都完全相同,它们都包含在shared_ptr<>
我不保存任何可能无效的迭代器,它只是通过擦除列表中的随机元素而崩溃。 我不知道从哪里开始。
答案 0 :(得分:2)
您是否在容器内使用std::auto_ptr
?
auto_ptr
,只应谨慎使用。
auto_ptr
不能很好地复制,所以永远不应该使用内部容器。
Why it is wrong to use std::auto_ptr<> with standard containers
如果C ++ 11不可用,请使用std::shared_ptr
或其他智能指针(例如来自boost)。
答案 1 :(得分:1)
我找到了答案:
破坏STL-Cotainers的常见原因是线程安全。
如果您正在同时修改容器,它可能会在随机位置中断,如果您尝试迭代它,您将只看到此破坏。
在我的例子中,有一个并行的“push_front”操作,它修改了容器,并发生了典型的数据争用。
看到这种行为的典型特征是,当列表具有合理的大小时,但是如果您在调试器中检查它,它将仅显示有用的值直到某个点,并且仅从那里(error)
。
我设法通过在push_front周围添加一个写锁来修复它。
我看到这种行为的另一种情况是,当我有一个堆栈溢出并销毁我的std :: list base。根据覆盖的字节数量,即使大小可能在合理的范围内,但整个容器(不像上面描述的情况,第一个元素仍然是好的!)已损坏。
我希望有人做同样的编码,并且错过了一个锁定的必要性并尝试解决它,因为堆栈问题会发现这很有用!