C++笔记-构造内存泄漏检测类的基本思路
目錄
?
基本概念
代碼與實例
?
基本概念
這里主要的思路是,在一個對象在堆區創建后,就把他記錄下來,也就是把他記錄到某個地方,這個地方負責管理他(和Qt里面的對象樹有異曲同工之妙)下面這個例子,把創建的新對象放到了鏈表里面。
有個root結點,當有新的對象被new,就把這個新對象的地址,以及其他的信息,比如大小,在哪個函數,代碼在哪個文件,哪一行,以頭添加的方式進行記錄。
當析構,delete某個對象后使用先在對象鏈表中把這個對象踢出去,再使用free將其釋放掉!
那么判斷內存泄漏就只要遍歷那個對象鏈表,如果存在,就打印,就證明有內存泄漏!!!
要設計一個內存檢測類,就必須對默認的new進行改造!當然這個delete也要被改造。
這里new會被改造,所以在代碼里面構造內存泄漏檢測類的時候,一般使用malloc進行分配。? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ??
?
代碼與實例
程序運行截圖如下:
源碼如下:
myleakdetector.h
#ifndef MYLEAKDETECTOR_H #define MYLEAKDETECTOR_H //我們要設計一個內存檢查,就必須對默認的new做改造 //打樁 void* operator new(size_t _size, char* file, unsigned int _line); void* operator new[](size_t _size, char* file, unsigned int _line);#ifndef __NEW__OVERLOADED #define new new(__FILE__,__LINE__) #endifclass MyLeakDetector { public:static unsigned int callCount;MyLeakDetector() noexcept{++callCount;}~MyLeakDetector(){if(--callCount == 0)LeakDetector();} private:static unsigned int LeakDetector() noexcept; };static MyLeakDetector _exit_counter;#endif // MYLEAKDETECTOR_Hmain.cpp
#include <iostream> using namespace std;class FClassErr{public:FClassErr(int n){if(n <= 0)throw 101;data = new int[n];}~FClassErr(){delete []data;}private:FClassErr(const FClassErr &){}FClassErr & operator = (const FClassErr &){}int *data; };int main() {int *a = new int;int *b = new int[1024];//delete a;try {FClassErr *e = new FClassErr(1);delete e;} catch (int &ex) {cout << "There is an anomaly!" << endl;}return 0; }myleakdetector.cpp
#include<iostream> #include<cstring> //定義宏,從而實現new的管理 #define __NEW__OVERLOADED #include "myleakdetector.h" using namespace std;typedef struct _MemoryList{struct _MemoryList *next,*prev;size_t size;//bool isArray;//是否有申請數組char *file;unsigned int line; }_MemoryList;static unsigned long _memory_allocated = 0; //未釋放的內存的大小static _MemoryList _root ={&_root,&_root,//第一個元素自引,他引指針0,false,NULL,0 };unsigned int MyLeakDetector::callCount = 0;//開始分配內存 void* AllocMemory(size_t _size,bool _array,char * _file,unsigned _line){size_t newSize = sizeof(_MemoryList)+_size;//用malloc來分配_MemoryList *newElem =(_MemoryList*)malloc(newSize);newElem->next = _root.next;newElem->prev = &_root;newElem->size = _size;newElem->isArray = _array;newElem->file= NULL;if(_file){newElem->file = (char*)malloc(strlen(_file)+1);strcpy(newElem->file,_file);}newElem->line=_line;//更新列表_root.next->prev = newElem;_root.next = newElem;//記錄到未釋放的內存_memory_allocated += _size;return (char*)newElem + sizeof(_MemoryList); }void DeleteMemory(void* _ptr,bool _array){_MemoryList *currentElem = (_MemoryList*)((char*)_ptr -sizeof(_MemoryList));if(currentElem->isArray != _array)return;currentElem->prev->next = currentElem->next;currentElem->next->prev = currentElem->prev;if(currentElem->file)free(currentElem->file);free(currentElem); }//重載new運算符 void *operator new(size_t _size){return AllocMemory(_size,false,NULL,0); }void *operator new[](size_t _size){return AllocMemory(_size,true,NULL,0); }void *operator new(size_t _size,char *file,unsigned _line){return AllocMemory(_size,false,file,_line); }void *operator new[](size_t _size,char *file,unsigned _line){return AllocMemory(_size,true,file,_line); }//重載delete void operator delete(void* _ptr) noexcept{DeleteMemory(_ptr,false); }void operator delete[](void* _ptr) noexcept{DeleteMemory(_ptr,true); }unsigned int MyLeakDetector::LeakDetector(void) noexcept{unsigned int count =0;_MemoryList *ptr = _root.next;while(ptr && ptr != &_root){if(ptr->isArray)cout << "The array leak []";elsecout << "leak";cout << ptr << " The size is : " << ptr->size << endl;if(ptr->file)cout << "location is " <<ptr->file<< ", The row is " << ptr->line << endl;elsecout << "no such file!" << endl;++count;ptr=ptr->next;}if(count)cout << "The leaking count is " << count << endl;return count; }?
總結
以上是生活随笔為你收集整理的C++笔记-构造内存泄漏检测类的基本思路的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Flask笔记-使用Cookie及简单加
- 下一篇: Spring Boot中通过Accept