2011-07-02 83 views
1

我再次遇到內存分配問題,我找不到原因。std :: string構造函數中的內存分配/堆損壞

當我運行在調試模式下我收到以下錯誤消息的程序(我試着將它儘可能準確地翻譯):

Windows已經引發了LogoColorDetector.exe一個斷點。這可以通過堆損壞這表明在LogoColorDetector.exe還是有問題的加載的DLL的一個[...]引起

當我調試我發現,問題似乎在以下行發生程序:

const std::string& support::Image::getFilepath() const 
{ 
    return this->_filePath; 
} 

我已經檢查如果在imgTrain [j]的圖像 - 物體具有正確_filePath字符串: -

std::string tmp = imgTrain2[j]->getFilepath(); 

的getFilepath()函數是如下實施。所以我認爲這個問題在別的地方。有趣的是,包含有問題的行的函數似乎工作。這只是我第二次調用失敗的函數,這表明問題不在函數本身中。我不分配任何內存我也不除了什麼是可能通過的std :: string

間接完成萬一功能刪除任何它是一個任何人的幫助,這裏的堆棧跟蹤:

msvcr100d.dll!_heap_alloc_base(unsigned int size) Zeile 55 C 
msvcr100d.dll!_heap_alloc_dbg_impl(unsigned int nSize, int nBlockUse, const char * szFileName, int nLine, int * errno_tmp) Zeile 431 + 0x9 Bytes C++ 
msvcr100d.dll!_nh_malloc_dbg_impl(unsigned int nSize, int nhFlag, int nBlockUse, const char * szFileName, int nLine, int * errno_tmp) Zeile 239 + 0x19 Bytes C++ 
msvcr100d.dll!_nh_malloc_dbg(unsigned int nSize, int nhFlag, int nBlockUse, const char * szFileName, int nLine) Zeile 302 + 0x1d Bytes C++ 
msvcr100d.dll!malloc(unsigned int nSize) Zeile 56 + 0x15 Bytes C++ 
msvcr100d.dll!operator new(unsigned int size) Zeile 59 + 0x9 Bytes C++ 
LogoColorDetector.exe!std::_Allocate<char>(unsigned int _Count, char * __formal) Zeile 36 + 0xf Bytes C++ 
LogoColorDetector.exe!std::allocator<char>::allocate(unsigned int _Count) Zeile 187 + 0xb Bytes C++ 
LogoColorDetector.exe!std::basic_string<char,std::char_traits<char>,std::allocator<char> >::_Copy(unsigned int _Newsize, unsigned int _Oldlen) Zeile 1933 + 0x12 Bytes C++ 
LogoColorDetector.exe!std::basic_string<char,std::char_traits<char>,std::allocator<char> >::_Grow(unsigned int _Newsize, bool _Trim) Zeile 1963 + 0x13 Bytes C++ 
LogoColorDetector.exe!std::basic_string<char,std::char_traits<char>,std::allocator<char> >::assign(const std::basic_string<char,std::char_traits<char>,std::allocator<char> > & _Right, unsigned int _Roff, unsigned int _Count) Zeile 902 + 0xe Bytes C++ 
LogoColorDetector.exe!std::basic_string<char,std::char_traits<char>,std::allocator<char> >::basic_string<char,std::char_traits<char>,std::allocator<char> >(const std::basic_string<char,std::char_traits<char>,std::allocator<char> > & _Right) Zeile 546 C++ 
LogoColorDetector.exe!compareClasses(support::ImageCollection * coll, support::ImageClass * cl1, support::ImageClass * cl2, float * mean, float * var) Zeile 111 + 0x22 Bytes C++ 

有沒有人有什麼可能會導致此問題的想法?

感謝您的幫助。

- 編輯 -

試圖與視覺檢漏儀的建議。它不會顯示任何內容,直到上面提到的錯誤消息彈出並說內存在釋放後被修改。有沒有辦法找出什麼對象與內存地址相關 - 內存轉儲似乎不是很有幫助。

爲了使事情變得更加myterious我嘗試添加以下行:

std::string tmp = imgTrain2[j]->getFilepath(); 
std::string t2Path = imgTrain2[j]->getFilepath(); 

現在第一線的正確執行和第二線失敗。

+0

怎麼樣getFilepath()返回一個副本,而不是參考? 'const std :: string support :: Image :: getFilepath()const' – karlphillip

回答

9

當運行時檢測到堆損壞時,堆是已損壞。這意味着之前的操作會搞砸它(例如:你寫了超出數組範圍的東西,你有損壞的指針等等。)。

使用可視化泄漏檢測器或任何可以在覆蓋內存位置的確切位置發出錯誤信號的工具運行程序(例如,這仍然可能不會顯示代碼中的錯誤,例如如果你早先損壞了一個指針,但至少它會給你一個提示什麼被損壞)。

更新:一些增編大衛的回答(對不起,等不允許長時間評論)

要完成的比喻:有在你的程序中的錯誤。當包含bug的行被執行時,它可能會產生錯誤。它會覆蓋存儲有關(一個)分配的內存塊的信息的堆的一部分。運行時無法識別此內存段屬於您的進程,因此您應該可以寫入它。沒有失敗。現在稍後(也許在應用程序的完全不同的部分),您嘗試分配新內存,新運算符調用heap_alloc_以獲取新的內存塊。 alloc的代碼遍歷分配的內存塊的鏈,並在那裏發現一些垃圾。它觸發了一個未能讓你知道事情真的很糟糕的事情。現在你必須在你的代碼中找到觸發錯誤的錯誤。沒有一些工具,你必須檢查你的整個代碼尋找一個錯誤。

+0

+1非常好的解釋。 – Josh

3

當你把垃圾堆倒掉時,錯誤的來源和檢測在位置和時間上是很常見的。故障,錯誤和故障之間存在很大差異。

通過類推,想一想在內存中有一點零,但由於某種原因切換到永久卡住在一個狀態。這是一個錯誤。沒有後果。假設該位上的下一個操作是將其命令開啓。該命令隱藏了故障;從某種意義上說問題不存在。讀者將收到一個值,正確的價值。命令它爲零並且錯誤再次爲真,但這仍然是一個沒有問題的問題。直到讀者讀取一個應該爲0的位時,問題纔會顯現出來。此時故障觸發了一個錯誤。這仍然不是問題;錯誤可能沒有影響,失敗的比特碰巧是pi的存儲值的尾數的最低有效位。有些故障會造成問題。例如,錯誤的位故障可能使(實際上已經造成)太空船失聰。當錯誤導致系統以某種方式表現不佳時,錯誤會觸發失敗。

你的代碼沿線的某處在分配的內存的某個部分上做了一點點跳舞。那是錯誤。你的代碼繼續快樂地執行,直到它試圖訪問跳舞的內存:一個錯誤。其中一些錯誤可能是良性的。你的程序繼續愉快地繼續下去,直到遇到一些重要的代碼,它很可能試圖通過跳舞的內存訪問它。

我懷疑你寫在imgTrain2[j]的那一行。現在你有一個糟糕的指針。

+0

'imgTrain2 [j]'可能沒問題。即使它不好,你仍然不會看到這個錯誤消息。堆已損壞。不錯的寫作,雖然:) –