C++内存泄漏处理
2016-02-28 14:05
357 查看
/* 功能: 我们重载了operator new是全局的,new运算符先调用我们重载的operator new,再调用相应的构造函数, 一般来讲都是使用placement new直接在operator new返回的指针上调用相应的构造函数。 这里如果我们重载的是类的operator new会优先调用类内的,而不是全局的,即使类内的调用错误也不会向外找了。 */ 【memchecker.h】 struct MemIns { void* pMem; int m_nSize; char m_szFileName[256]; int m_nLine; MemIns* pNext; }; class MemManager { public: MemManager(); ~MemManager(); private: MemIns *m_pMemInsHead; int m_nTotal; public: static MemManager* GetInstance(); void Append(MemIns *pMemIns); void Remove(void *ptr); void Dump(); }; void* operator new(size_t size, const char* szFile, int nLine); void operator delete(void* ptr, const char* szFile, int nLine); void operator delete(void* ptr); void* operator new[] (size_t size, const char* szFile, int nLine); void operator delete[](void* ptr, const char* szFile, int nLine); void operator delete[](void* ptr); 【memchecker.cpp】 #include"memchecker.h" #include<stdio.h> #include <stdlib.h> #include<malloc.h> #include<string.h> MemManager::MemManager() { m_pMemInsHead=NULL; m_nTotal=NULL; } MemManager::~MemManager() { } void MemManager::Append(MemIns* pMemIns) { pMemIns->pNext=m_pMemInsHead; m_pMemInsHead = pMemIns; m_nTotal+= m_pMemInsHead->m_nSize; } void MemManager::Remove(void* ptr) { MemIns* pCur = m_pMemInsHead; MemIns* pPrev = NULL; while(pCur) { if(pCur->pMem == ptr) { if(pPrev) { pPrev->pNext = pCur->pNext; } else { m_pMemInsHead = pCur->pNext; } m_nTotal -= pCur->m_nSize; free(pCur); break; } pPrev = pCur; pCur = pCur->pNext; } } void MemManager::Dump() { MemIns* pp = m_pMemInsHead; while(pp) { printf( "File is %s\n", pp->m_szFileName ); printf( "Size is %d\n", pp->m_nSize ); printf( "Line is %d\n\n", pp->m_nLine ); pp = pp->pNext; } } void PutEntry(void *ptr, int size, const char* szFile, int nLine) { MemIns* p = (MemIns*)(malloc(sizeof(MemIns))); if(p) { strcpy(p->m_szFileName, szFile); p->m_nLine = nLine; p->pMem = ptr; p->m_nSize = size; MemManager::GetInstance()->Append(p); } } void RemoveEntry(void* ptr) { MemManager::GetInstance()->Remove(ptr); } void* operator new(size_t size, const char* szFile, int nLine) { void* ptr = malloc(size); PutEntry(ptr, size, szFile, nLine); return ptr; } void operator delete(void *ptr) { RemoveEntry(ptr); free(ptr); } void operator delete(void* ptr, const char* file, int line) { RemoveEntry(ptr); free(ptr); } void* operator new[](size_t size, const char* szFile, int nLine) { void * ptr = malloc(size); PutEntry(ptr, size, szFile, nLine); return ptr; } void operator delete[](void *ptr) { RemoveEntry(ptr); free(ptr); } void operator delete[](void* ptr ,const char* szFile, int nLine) { RemoveEntry(ptr); free(ptr); } /* 重载new思想: operator new的重载是可以有自定义参数的,那么我们如何利用自定义参数获取更多的信息呢,这里一个很有用的做法 就是给operator new添加两个参数:char* file, int line,这两个参数记录new运算符的位置,然后再在new时 将文件名和行号传入,这样我们就能在分配内存失败时给出提示:输出文件名和行号。 那么如何获取当前语句所在文件名和行号呢,windows提供两个宏:__FILE__和__LINE__。 利用它们可以直接获取到文件名和行号,也就是 new(__FILE__, __LINE__) 由于这些都是不变的, 因此可以再定义一个宏:#define new new(__FILE__, __LINE__)。这样我们就只需要定义这个宏, 然后重载operator new即可。 */ #define new new(__FILE__,__LINE__) MemManager m_memTracer; MemManager* MemManager::GetInstance() { return &m_memTracer; } int main() { int *plen =new int ; *plen=10; //delete plen; //注意这两次delete走的都是delete重载void*参数的,没有走参数多的那项 char *pstr=new char[35]; strcpy(pstr,"hello memory leak"); //delete[] pstr; //同上 m_memTracer.Dump(); system("pause"); return 0; }
相关文章推荐
- C语言 包含结构的结构
- C++产生随机数
- C++面试题
- C语言 结构体作为函数的参数
- c语言:求三个数中的最大值(双分支结构)
- C语言(函数与宏)
- Eclipse下搭建C/C++开发环境教程
- How computer work?
- 最新首发Eclipse+CDT+android-ndk写纯c++安卓应用(附openGL Es)
- C语言实现双向非循环链表(不带头结点)的清空
- C/C++中define定义的常量与const常量
- 《你必须知道的495个C语言问题》知识笔记及补充
- C/C++中define定义的常量与const常量
- POJ 2362
- VS2010 C++ 操作Excel表格的编程实现
- C++中将数组作为形参时防止访问越界的几种方法
- C语言 单链表的 反序输出 与 反转
- effective c++读书笔记1,导读
- C++程序设计课程主页-2015级
- C++中的RVO和NRVO