2010-06-08 81 views
10

我有一個問題有關的std :: string可能的內存泄漏的valgrind許多警告,像這樣的:C++的std :: string池,調試版本?的std :: string和Valgrind的問題

120 bytes in 4 blocks are possibly lost in loss record 4,192 of 4,687 
    at 0x4A06819: operator new(unsigned long) (vg_replace_malloc.c:230) 
    by 0x383B89B8B0: std::string::_Rep::_S_create(unsigned long, unsigned long, std::allocator<char> const&) (in /usr/lib64/libstdc++.so.6.0.8) 
    by 0x383B89C3B4: (within /usr/lib64/libstdc++.so.6.0.8) 
    by 0x383B89C4A9: std::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string(char const*, unsigned long, std::allocator<char> const&) (in /usr/lib64/libstdc++.so.6.0.8) 

我想知道:

  • 做std :: string(GCC 4.1.2)使用任何內存池?
  • 如果是這樣,是否有任何方法來禁用池(以調試版本等形式)?

回答

6

檢查FAQ描述被抑制。有關於「容器內存泄漏」的部分。你應該

  • 檢查Valgrind的
  • 版本
  • 使用你的程序的調試版本(和未優化)
  • ,如果需要定義GLIBCXX_FORCE_NEW。 (這是一個環境變量,會影響你的程序的運行時的行爲,而不是編譯時#define如您所想。)
2

如果我沒有記錯,許多STL分配器實現某種記憶保持的。 IE瀏覽器不會立即釋放分配的內存,而是保留並重用它。我的STL實現中分配的內存中valgrind肯定有很多誤報。

我已經找到了解決這一問題的最佳方式是(簡單)使用抑制文件。

0

我只是有這個問題,對我來說,那是因爲我用庫的開發版本鏈接,但我的測試代碼被撿舊的系統安裝的版本。這些變化足夠微妙,它可以鏈接和運行,但沒有任何明顯的問題,但Valgrind會檢測到奇怪的泄漏。使用ldd代替valgrind確認它正在拾取錯誤的庫文件。設置LD_LIBRARY_PATH正確地修復它,雖然正確的解決方案是增加庫版本,因爲它顯然不會向後兼容,如果你發生這種情況。

當一個對象沒有被正確銷燬時,我也看到了這個問題,比如一個virtual函數缺少一個virtual析構函數。當類放入指向基類的類中然後銷燬時,只會運行基類析構函數,從而泄漏派生類中分配的任何內容,例如示例中的std::string實例。這裏的提示是檢查哪個類正在使用泄漏的string,並且按照類的層次返回到基類,並確認它具有顯式的virtual析構函數,甚至是空的。我假設他們是隱含的,如果在一個班級中有virtual職能,但顯然不是,並且海灣合作委員會並沒有警告你。

0

我有這個問題,因爲我的程序終止由於未捕獲到異常。顯然,未捕獲異常的處理程序不會清理所有內容。