2015-10-13 43 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