2010-03-20 289 views
26

我的程序中有一個相當嚴重的錯誤 - 偶爾會調用new()拋出bad_alloc。調試策略找到bad_alloc的原因

從文檔我可以找到關於bad_alloc的,它似乎被拋出這些原因:

  1. 當計算機運行的內存(這肯定是不會發生的,我有4GB的內存,程序在使用少於5MB(在taskmanager中檢查)時拋出bad_alloc,而沒有任何嚴重的後臺運行)。

  2. 如果內存變得過於分散,無法分配新塊(這再次不太可能 - 我分配的最大塊大小約爲1KB,並且在崩潰發生之前不會超過100次)。

基於這些描述,我並沒有真正的bad_alloc可以拋出的地方。

但是,我正在運行的應用程序運行多個線程,這可能會導致問題。通過測試單個線程上的所有對象,一切似乎都能順利進行。我能想到的唯一另外一件事情就是在這裏發生的可能是由於在同一時間在多個地方調用new()而導致的某種競爭條件,但我嘗試添加互斥體以防止該行爲沒有效果。

因爲程序有幾百行,我不知道問題的實際位置,所以我不確定要發佈什麼代碼片段。相反,我想知道是否有任何工具可以幫助我測試這種事情,或者是否有任何一般策略可以幫助我解決這個問題。

我正在使用Microsoft Visual Studio 2008與Poco進行線程化。

回答

16

商量好了另一個可能的問題是,當你提到的程序比5MB少用,你不提它的空間有多大試圖分配。你可能有一些競爭條件會破壞你用來確定分配大小的值,並且它可能試圖分配37TB或某些廢話。

我想不太可能,但值得檢查。

+0

其實這就是問題所在......不知道問題出在哪裏,但是有很多變形的變量在奇怪的地方四處遊蕩 - 看起來就像某處存在競爭條件。謝謝! – Salami 2010-03-20 05:17:42

+0

這就是我的情況......我以爲我在調用'new char [_len]',但是當'len'沒有被初始化時,我正在調用'new char [len]',所以可能有一些很大的數字。這真的有助於思考我要求多少空間,並更仔細地看待價值。感謝你的回答。 – flcoder 2018-01-29 19:54:08

3

很少澄清:

所有進程都在窗口獲得4GB虛擬內存,其中有2GB是用戶空間和剩餘的內核空間。 4GB的RAM不會對虛擬內存作出貢獻,而是用於物理內存。

在2GB的內存中,所有的EXE,DLL都會被加載,很難有1.6 - 1.7GB的內存分配空間。在這個內存中,如果沒有連續的內存分配,那麼內存分配失敗。

+0

你知道關於linux/unix系統他們分配多少? – anish 2010-03-20 04:45:49

20

當您有一個覆蓋堆使用的指針來管理它用來分配的內存池時,也會引發bad_alloc。

最常見的原因是您正在寫入已分配內存塊的末尾(或在開始之前,但不常見)。在釋放內存塊後寫入內存塊幾乎同樣常見。這被稱爲堆腐敗。另外,我應該注意到,Windows中的32位進程最多有2GB的地址空間(對於支持大地址的程序,爲3GB)。無論您安裝了多少RAM,內存是虛擬的,並且在地址空間用盡之前分配都不會失敗,即使您只有1GB內存。

下面是用C內存損壞++ http://www.eventhelix.com/RealtimeMantra/Basics/debugging_software_crashes_2.htm

+0

謝謝你在這裏的信息。 – Salami 2010-03-20 05:20:20

1

bad_alloc也可以被其他代碼拋出。

我見過它被設計用於STL容器的限制內存池使用。當大小限制被擊中時,它會拋出bad_alloc,軟件必須處理它。

0

我以前實際上遇到過這個問題,並且通過清理和重建項目來解決問題。當你有奇怪的行爲時,總是值得一試(除非它是一個需要數小時編譯的巨大項目)。