程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> 輕輕松松做內存檢測

輕輕松松做內存檢測

編輯:C++入門知識

剛接觸C++的時候總感覺內存洩露是很可怕的事,覺得手足無措,直到有一天發現心裡的巨石居然是那麼小的一個case。
方法一:利用CRT調試堆函數
舉例說明:
#ifdef _DEBUG
#define CRTDBG_MAP_ALLOC
#include <crtdbg.h>
#include <stdlib.h>
#define  new new(_NORMAL_BLOCK,__FILE__,__LINE__)
#endif

int main()
{
 char *p = new char[200];
#ifdef _DEBUG
 _CrtDumpMemoryLeaks();
 _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_REPORT_FLAG | _CRTDBG_LEAK_CHECK_DF);
#endif

 return 0;
}

輸出信息:
Detected memory leaks!
Dumping objects ->
f:\test\highquality\c++primer\main.cpp(10) : {69} normal block at 0x00396990, 200 bytes long.
 Data: <                > CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD
Object dump complete.

分析:
  {xxx} — 表示程序運行後第xxx次內存分配發生了洩漏,即內存分配編號;
  xxx block — 表示內存塊類型,包括三種:普通(normal)、客戶端(client)和運行時(CRT);
  at 0x00396990 — 表示發生洩漏的內存地址,用十六進制表示;
  xx bytes long — 表示發生洩漏的內存大小;
  Data:xxx — 表示內存數據信息,一般輸出前16字節的內容。

利用_CrtSetBreakAlloc()設置分配指定的內存時,中斷,然後查看調用棧。
#ifdef _DEBUG
#define CRTDBG_MAP_ALLOC
#include <crtdbg.h>
#include <stdlib.h>
#define  new new(_NORMAL_BLOCK,__FILE__,__LINE__)
#endif

int main()
{
 _CrtSetBreakAlloc(69);
 char *p = new char[200];
#ifdef _DEBUG
 _CrtDumpMemoryLeaks();
 _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_REPORT_FLAG | _CRTDBG_LEAK_CHECK_DF);
#endif

 return 0;
}

方法二:使用VLD工具
Visual Leak Detector是一款用於Visual C++的免費的內存洩露檢測工具。相比較其它的內存洩露檢測工具,它在檢測到內存洩漏的同時,具有如下特點:  
(1).可以得到內存洩漏點的調用堆棧,如果可以的話,還可以得到其所在文件及行號;   
(2).可以得到洩露內存的完整數據;   
(3).可以設置內存洩露報告的級別;   
(4).它是一個已經打包的lib,使用時無須編譯它的源代碼。而對於使用者自己的代碼,也只需要做很小的改動;   
(5).他的源代碼使用GNU許可發布,並有詳盡的文檔及注釋。對於想深入了解堆內存管理的讀者,是一個不錯的選擇。
1.下載VLD工具 http://www.codeproject.com/tools/visualleakdetector.asp
2.使用 解壓之後得到vld.h, vldapi.h, vld.lib, vldmt.lib, vldmtdll.lib, dbghelp.dll等文件。將.h文件和.lib文件拷貝到你要檢測的工程文件所在的目錄裡(只針對此工程),將dbghelp.dll拷貝到你的程序的運行目錄下。
3.用法:在包含入口函數的.cpp文件中加入語句#include "vld.h"即可。
編譯正確後,在debug方式下運行:查看VC的輸出信息:
有內存洩露顯示:"WARNING: Visual Leak Detector detected memory leaks!"
沒有內存洩露,此輸出的信息為:"No memory leaks detected."
4.舉例說明:
#include <iostream>
#include <string>
#include "vld.h"

using namespace std;

int main()
{  
 int *n = new int[10];
 string *s = new string("hello!\n");

 cout << n;
 cout << *s;

 return 0;
}

輸出信息中包含以下語句:
Visual Leak Detector Version 1.0 installed (multithreaded static).
WARNING: Visual Leak Detector detected memory leaks!
---------- Block 84 at 0x003E6CB8: 32 bytes ----------
  Call Stack:
    f:\test\highquality\c++primer\main.cpp (10): main
    f:\dd\vctools\crt_bld\self_x86\crt\src\crt0.c (327): __tmainCRTStartup
    f:\dd\vctools\crt_bld\self_x86\crt\src\crt0.c (196): mainCRTStartup
    0x7C817077 (File and line number not available): RegisterWaitForInputIdle
  Data:
    00 00 00 00    CD CD CD CD    68 65 6C 6C    6F 21 0A 00     ........ hello!..
    CD CD CD CD    CD CD CD CD    07 00 00 00    0F 00 00 00     ........ ........

---------- Block 83 at 0x003E6C50: 40 bytes ----------
  Call Stack:
    f:\dd\vctools\crt_bld\self_x86\crt\src\newaop.cpp (7): operator new[]
    f:\test\highquality\c++primer\main.cpp (9): main
    f:\dd\vctools\crt_bld\self_x86\crt\src\crt0.c (327): __tmainCRTStartup
    f:\dd\vctools\crt_bld\self_x86\crt\src\crt0.c (196): mainCRTStartup
    0x7C817077 (File and line number not available): RegisterWaitForInputIdle
  Data:
    CD CD CD CD    CD CD CD CD    CD CD CD CD    CD CD CD CD     ........ ........
    CD CD CD CD    CD CD CD CD    CD CD CD CD    CD CD CD CD     ........ ........
    CD CD CD CD    CD CD CD CD                                   ........ ........

Visual Leak Detector detected 2 memory leaks.
“C++primer.exe”: 已卸載“C:\WINDOWS\system32\dbghelp.dll”
“C++primer.exe”: 已卸載“C:\WINDOWS\system32\version.dll”
Visual Leak Detector is now exiting.
程序“[1740] C++primer.exe: 本機”已退出,返回值為 0 (0x0)。

代碼改為:
#include <iostream>
#include <string>
#include "vld.h"

using namespace std;

int main()
{  
 int *n = new int[10];
 string *s = new string("hello!\n");

 cout << n;
 cout << *s;

 delete [] n;
 delete s;

 return 0;
}

輸出信息中包含以下語句:
Visual Leak Detector Version 1.0 installed (multithreaded static).
No memory leaks detected.
“C++primer.exe”: 已卸載“C:\WINDOWS\system32\dbghelp.dll”
“C++primer.exe”: 已卸載“C:\WINDOWS\system32\version.dll”
Visual Leak Detector is now exiting.
程序“[4272] C++primer.exe: 本機”已退出,返回值為 0 (0x0)。

 

作者:one_in_one

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved