您好,登錄后才能下訂單哦!
小編給大家分享一下windows下C/C++內(nèi)存泄露檢測的方法,相信大部分人都還不怎么了解,因此分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后大有收獲,下面讓我們一起去了解一下吧!
利用Visual Studio調(diào)試器和CRT庫提供的檢測(malloc和new均適用)
程序只從單一位置退出時:
1.需要以下頭文件:
#define _CRTDBG_MAP_ALLOC #include<stdlib.h> #include<crtdbg.h>
通過包含crtdbg.h,將malloc和free分別映射到_malloc_dbg和_free_dbg,用于內(nèi)存分配和釋放的跟蹤。
#define _CRTDBG_MAP_ALLOC語句用于提供額外的信息,非絕對必要。
2.在程序退出位置前使用以下語句:
_CrtDumpMemoryLeaks();
該語句會在輸出窗口顯示內(nèi)存泄露信息。
測試代碼
#define _CRTDBG_MAP_ALLOC #include<stdio.h> #include<stdlib.h> #include<crtdbg.h> #define NUM 10 int main() { char *test; test = (char*)malloc(NUM * sizeof(char)); _CrtDumpMemoryLeaks(); return 0; }
輸出結(jié)果
使用_CRTDBG_MAP_ALLOC時:
未使用_CRTDBG_MAP_ALLOC時:
如果將程序中的:
char *test; test = (char*)malloc(NUM * sizeof(char));
替換為:
char* name = new char[10];
也會得到同樣的結(jié)果(內(nèi)存位置由于自動分配有所不同):
程序從多個位置退出時:
1.同樣包含上述頭文件
2.在每個會退出程序的函數(shù)(包括main函數(shù))開始處包含以下代碼:
_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
程序會在退出時自動調(diào)用_CrtDumpMemoryLeaks();。
測試代碼
#define _CRTDBG_MAP_ALLOC #include<stdio.h> #include<stdlib.h> #include<crtdbg.h> #define NUM 10 void test1(); void test2(); int main() { _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF); char *test; test = (char*)malloc(NUM * sizeof(char)); int a; puts("input a number"); scanf_s("%d", &a, sizeof(int)); if (a > 10) test1(); else if(a<20) test2(); else puts("exit point 3"); return 0; } void test1() { _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF); puts("exit point 1"); exit(EXIT_SUCCESS); } void test2() { _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF); puts("exit point 2"); exit(EXIT_SUCCESS); }
輸出結(jié)果
當程序不大時,內(nèi)存泄露位置可以輕易通過肉眼分辨或者代碼審計發(fā)現(xiàn)。但是當程序較大的時候,就難以發(fā)現(xiàn)具體發(fā)生內(nèi)存泄露的位置。此時可以通過CRT庫的_CrtMenState結(jié)構(gòu)儲存內(nèi)存狀態(tài)。
使用該結(jié)構(gòu)類型需要定義變量用于儲存內(nèi)存狀態(tài):
_CrtMenState s1,s2,s3;
檢測指定位置內(nèi)存需要用到_CrtMenCheckPoint結(jié)構(gòu):
_CrtMenCheckPoint(&s1);
該語句將當前位置的內(nèi)存狀態(tài)傳遞到_CrtMenState結(jié)構(gòu)變量s1中。
檢測兩個位置之間的內(nèi)存狀態(tài)需要用到_CrtMenDifference()函數(shù),同時需要一個新的_CrtMenState結(jié)構(gòu)變量用于存儲狀態(tài)之間的差異:
_CrtMemCheckpoint( &s1 ); _CrtMemCheckpoint( &s2 ); _CrtMemDifference( &s3, &s1, &s2);
轉(zhuǎn)儲_CrtMenState結(jié)構(gòu)的內(nèi)容需要用到_CrtMemDumpStatistics函數(shù):
_CrtMenDumpStatics(&s3);
測試代碼
#define _CRTDBG_MAP_ALLOC #include<stdio.h> #include<stdlib.h> #include<crtdbg.h> #define NUM 10 _CrtMemState s1, s2, s3; void MEM(char *str, int n); int main() { _CrtMemCheckpoint(&s1); char *test=NULL; MEM(test, NUM); _CrtMemCheckpoint(&s2); puts("test\n"); _CrtMemDifference(&s3, &s1, &s2); _CrtMemDumpStatistics(&s3); return 0; } void MEM(char *str, int n) { str = (char*)malloc(n * sizeof(char)); }
輸出結(jié)果
當s1和s2之間調(diào)用了函數(shù)MEN()時:
當刪去程序中的
MEN(test, NUM);
即s1和s2之間沒有調(diào)用MEN()函數(shù)時:
如果單純使用_CrtDumpMemoryLeaks();,只能顯示內(nèi)存分配的位置,即函數(shù)MEN()中分配內(nèi)存語句的位置,而不能定位到是哪一次對函數(shù)MEN()調(diào)用導致的內(nèi)存泄露,而通過結(jié)構(gòu)_CrtMenState,可以得到語句之間是否存在內(nèi)存分配,從而定位出內(nèi)存泄露的位置。
以上是“windows下C/C++內(nèi)存泄露檢測的方法”這篇文章的所有內(nèi)容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內(nèi)容對大家有所幫助,如果還想學習更多知識,歡迎關(guān)注億速云行業(yè)資訊頻道!
免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。