2012-04-24 92 views
0

全部,任何人都可以告訴我一個好方法或工具來檢測Visual Studio中的內存泄漏這些代碼?我已經測試了crt調試,但是當我中止調試過程時(shift + f5),內存泄漏報告不會出現在調試窗口中。如何找到一種方法來檢測此代碼中的內存泄漏?

void fun1() 
{ 
    int * pInt = new int; 
    return; 
} 
void Execute(void) 
{ 
    while(true) 
    { 
     cout<<"I will sleep for 1 second..."<<endl; 
     ::Sleep(1000); 
     fun1(); 
    } 
    return; 
} 
int main() 
{ 
    Execute(); 
    return 0; 
} 

任何人都知道如何找到上述代碼的內存? 順便說一句,如果我選擇使用shared_ptr,內存泄漏不會再發生,對吧?

+4

我在等待答案,告訴你'delete pInt;'因爲他們還沒有讀完整個問題...... – 2012-04-24 15:18:14

+0

只有一個'new'語句,所以內存泄漏不應該很難找到:P – orlp 2012-04-24 15:19:30

+0

你是如何「中止流程」的?在正常的進程關閉期間CRT很可能會執行檢查 - 如果將while(true)改爲有限循環並讓進程退出,會發生什麼情況? – 2012-04-24 15:21:42

回答

0

是否將此添加到主要功能的頂部不起作用?

#if defined(DEBUG) | defined (_DEBUG) 
    _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF); 
#endif 

您必須以調試模式運行。

-1

我不知道VS,在Linux上我會用valgrind

+3

這是一個關於爲什麼VS中的泄漏檢測鉤子不會觸發的問題。 – 2012-04-24 15:23:37

+0

好吧,我問這個問題,我發現這個[MSDN頁面](http://msdn.microsoft.com/en-us/library/e5ewb1h3(v = vs.90).aspx)請特別注意評論部分,解釋你必須爲C++'new'做些什麼。 – 2012-04-24 15:26:50

+0

VS2010的類似頁面意味着有一個單獨的'#define'用於'operator new' – 2012-04-24 15:53:42

1

這裏的問題很簡單:當你中止一個進程時,泄漏內存或多或少被認爲是理所當然的 - 即使你的代碼通常不會泄漏,用調試器中止它也是(缺少非常好的運氣)無論如何都會泄漏內存。因此,當您使用調試器中止程序時,通常會報告內存泄漏的大多數工具都不會生效。

因此,要查看泄漏報告,您需要編寫代碼,在某些時候,它會自行退出,而不要求您使用調試器來終止它。如果你改變你的代碼是這樣的:

void fun1() 
{ 
    int * pInt = new int; 
    return; 
} 
void Execute(void) 
{ 
    for (int i=0; i<100000; i++) 
    { 
     //cout<<"I will sleep for 1 second..."<<endl; 
     //::Sleep(2000); 
     fun1(); 
    } 
    return; 
} 
int main() 
{ 
    Execute(); 
    return 0; 
} 

順便說一句,當你通過2000作爲參數傳遞給Sleep,你應該期望它睡覺至少2秒,不只是一個。目前,我已註釋掉coutSleep,所以它應該快速泄漏內存併產生泄漏報告。有了很多的輸出和睡覺,它會做同樣的事情,只是更慢,更吵鬧。

+0

我從個人經驗中知道,Memory Validator會報告泄漏等事情。所以這取決於所使用的工具。 – StarPilot 2012-05-25 20:38:01

0

問題是,當一個進程正在運行時,自動化進程很難判斷哪些內存被泄漏。在追蹤對象和內存塊引用的語言中,您可以隨時執行此操作,只需找到沒有引用的塊即可。在C/C++中沒有這樣的事情(除非你自己實現它,那是),所以你不能確定內存塊是否已經泄漏。

在這種情況下你可以做的一件事是觸發在你的流程生命中某個時間點拋出內存泄漏的函數,你知道這個函數不應該有任何泄漏。例如,假設您知道您的應用程序在Execute()while循環中每次迭代結束時都不應該有任何泄漏。然後,你可以做這樣的事情:

#include <crtdbg.h> 

void fun1() 
{ 
    int * pInt = new int; 
    return; 
} 
void Execute(void) 
{ 
    int i = 0; 
    while(true) 
    { 
     cout<<"I will sleep for 1 second..."<<endl; 
     ::Sleep(2000); 
     fun1(); 

     #ifdef _DEBUG 
     // dump any leaks every 100 iterations 
     if (++i % 100 == 0) 
      _CrtDumpMemoryLeaks(); 
     #endif 
    } 
    return; 
} 
int main() 
{ 
    Execute(); 
    return 0; 
} 

約_CrtDumpMemoryLeaks()和MSVC CRT庫的其他功能的信息,請參閱this page

我希望這會有所幫助。