c++内存泄露检测,长文慎入!

来源:互联网 发布:万能硬盘数据恢复软件 编辑:程序博客网 时间:2024/06/04 17:39

关于内存泄露的,今天无意想到,网上找了一下


本篇blog附带的所有工具和代码下载地址如下:

http://download.csdn.net/detail/zengraoli/5348827


文中的memcheck晚点的时候在把它打包成dll


一、使用Dbgview.exe

不多数都是用的Dbgview.exe,话说还不错,我一直想找的仅仅是一个检测内存泄露的class,没想到csdn上面问,找到了这么一个工具,参看csdn论坛链接http://bbs.csdn.net/topics/390452307

来个测试工程:

#include <iostream>#include "string"#include "vector"using namespace std;int main(){{char *str;str = new char[100 + 1];strcpy(str, "zengraoli");cout << str << endl;}_CrtDumpMemoryLeaks();   // 内存泄露检测return 0;}

Ctrl+F5后,在Dbgview.exe中出现了下面的信息:



Detected memory leaks

这个是提示

上面的测试不方便的地方:

但在这上面显然有不太好的地方,比如我需要知道哪一行导致的内存泄露,所以参考csdn blog的一篇文章:http://blog.csdn.net/iuhsihsow/article/details/8492363

再次修改:

#include "stdafx.h"#include <iostream>#include "string"#include "vector"using namespace std;#ifdef_DEBUG#define _CRTDBG_MAP_ALLOC#include <stdlib.h>#include <crtdbg.h>#define newEx   new(_NORMAL_BLOCK, __FILE__, __LINE__)#endifinline void EnableMemLeakCheck(){_CrtSetDbgFlag(_CrtSetDbgFlag(_CRTDBG_REPORT_FLAG) | _CRTDBG_LEAK_CHECK_DF);}int _tmain(int argc, _TCHAR* argv[]){EnableMemLeakCheck();char *str = newEx char[9 + 1];cout << str << endl;return 0;}



Ctrl+F5后,在Dbgview.exe中出现了下面的信息:



可以看到正是25行的地方导致内存泄露的

二、不使用Dbgview.exe,直接使用class

参考文章:http://www.cnblogs.com/FCoding/archive/2012/07/04/2576877.html

Code没来得及细看,能用就是了^_^,方便就行,枉自猜测一下原理----------重载了newdelete,对他俩进行一个计数,并记下行数,两个不为偶数,则就是代表已经出现内存泄露了

MemCheck.h

#ifndef MEMCHECK_H#define MEMCHECK_H#include <cstddef>  // for size_t// Hijack the new operator (both scalar and array versions)void* operator new(std::size_t, const char*, long);void* operator new[](std::size_t, const char*, long);#define new new (__FILE__, __LINE__)extern bool traceFlag;#define TRACE_ON() traceFlag = true#define TRACE_OFF() traceFlag = falseextern bool activeFlag;#define MEM_ON() activeFlag = true#define MEM_OFF() activeFlag = false#endif

MemCheck.cpp

#include <cstdio>#include <cstdlib>#include <cassert>using namespace std;#undef new// Global flags set by macros in MemCheck.hbool traceFlag  = true;bool activeFlag = false;namespace {// Memory map entry typestruct Info {void* ptr;const char* file;long  line;};// Memory map dataconst  size_t MAXPTRS = 10000u;Info   memMap[MAXPTRS];size_t nptrs = 0;// Searches the map for an addressint findPtr(void* p) {for (int i = 0; i < nptrs; ++i){if (memMap[i].ptr == p){return i;}}return -1;}void delPtr(void* p){int pos = findPtr(p);assert(p >= 0);// Remove pointer from mapfor (size_t i = pos; i < nptrs-1; ++i){memMap[i] = memMap[i+1];}--nptrs;}// Dummy type for static destructorstruct Sentinel {~Sentinel(){if (nptrs > 0) {printf("Leaked memory at:\n");for (size_t i = 0; i < nptrs; ++i){printf("\t%p (file: %s, line %ld)\n", memMap[i].ptr, memMap[i].file, memMap[i].line);}}else{printf("No user memory leaks!\n");}}};// Static dummy objectSentinel s;} // End anonymous namespace// Overload scalar newvoid* operator new(size_t siz, const char* file,   long line) {void* p = malloc(siz);if (activeFlag){if (nptrs == MAXPTRS){printf("memory map too small (increase MAXPTRS)\n");exit(1);}memMap[nptrs].ptr = p;memMap[nptrs].file = file;memMap[nptrs].line = line;++nptrs;}if (traceFlag) {printf("Allocated %u bytes at address %p ", siz, p);printf("(file: %s, line: %ld)\n", file, line);}return p;}// Overload array newvoid* operator new[](size_t siz, const char* file, long line){return operator new(siz, file, line);}// Override scalar deletevoid operator delete(void* p) {if (findPtr(p) >= 0) {free(p);assert(nptrs > 0);delPtr(p);if (traceFlag){printf("Deleted memory at address %p\n", p);}}else if (!p && activeFlag){printf("Attempt to delete unknown pointer: %p\n", p);}}// Override array deletevoid operator delete[](void* p){operator delete(p);}

那哥们的测试工程,挺不错的,有3种情况:

#include "stdafx.h"#include <iostream>#include <vector>#include <cstring>#include "MemCheck.h"   // Must appear last!using namespace std;void Test(){int *i = new int(0);}class MyClass{private:int *p;public:MyClass(){if(p != NULL){p = new int(0);}}~MyClass(){if(p != NULL){delete p;p = NULL;}}};void Test2(){int *i = NULL; // better for readi = new int(0);    int *&y = i; // pointer's referencedelete i;MyClass *pMyClass = new MyClass();std::vector<MyClass*> myClasses;myClasses.push_back(new MyClass());myClasses.push_back(new MyClass());std::vector<void*> myVector;myVector.push_back(new MyClass());myVector.push_back(new MyClass());delete (MyClass *)(myVector.at(0));delete myVector.at(1); // memory leak}class Foo {char* s;public:Foo(const char*s ) {this->s = new char[strlen(s) + 1];strcpy(this->s, s);}~Foo() {delete [] s;}};void Test3(){cout << "hello\n";int* p = new int;delete p;int* q = new int[3];delete [] q;/**//*delete r;*/vector<int> v;v.push_back(1);Foo s("goodbye");}int main() {TRACE_OFF();MEM_ON();Test();Test2();Test3();MEM_OFF();}

在我编译的时候,会出现一下提示:



运行的时候出现:



对这个cpp的使用说明:

1、使用时在工程中加入在MemCheck.h,而且这个.h文件应该放在所以头文件的后边,因为里面有这么一句代码:#undef new

2、用MEM_ON()MEM_OFF()来打开和关闭检测

3TRACE_ON()TRACE_OFF()用来打开或关闭检测结果的输出(上面的测试代码中使用没做检测结果的输出)

4、可以检测代码中使用了流、标准容器,以及某个类的构造函数分配了空间


原创粉丝点击