//LIst.hpp
#ifndef _LIST_H_ #define _LIST_H_ #include<iostream> using namespace std; template<class T> struct Node { T _value; Node<T>* _next; Node<T>(const T& value) : _value(value) , _next(NULL) {} }; template<class T> class List { public: List() :_head(NULL) {} void PushBack(const T&data); Node<T>* Find(const T&data); void Remove(Node<T>*del); void Print(); private: Node<T>*_head; }; template<class T> void List<T>::PushBack(const T&data) { Node<T>*tmp = new Node<T>(data); if (_head == NULL) { _head = tmp; return; } Node<T>*begin = _head; while (begin->_next) { begin = begin->_next; } begin->_next = tmp; } template<class T> Node<T>* List<T>::Find(const T&data) { if (_head == NULL) { return NULL; } Node<T>*begin = _head; while (begin) { if (begin->_value== data) { return begin; } begin = begin->_next; } return NULL; } template<class T> void List<T>::Remove(Node<T>*del) { if (_head == NULL) { return; } Node<T>*begin = _head; Node<T>*prev = _head; while (begin) { if (del == begin) { if (del == _head) { _head = _head->_next; } else { prev->_next = begin->_next; } delete del; return; } prev = begin; begin = begin->_next; } } template<class T> void List<T>::Print() { Node<T>*begin = _head; while (begin) { cout << begin->_value<<" "; begin = begin->_next; } } #endif //_LIST_H
#ifndef _MEM_H_ #define _MEM_H_ #include"List.hpp" #include<string> struct MemoryBlockInfo//内存块信息 { void* _ptr; string _filename; int _line; MemoryBlockInfo(void*ptr = NULL, string filename = "", int line = 0); bool operator==(const MemoryBlockInfo&m); friend ostream& operator<<(ostream& out, MemoryBlockInfo&m); }; class MemoryManage//单例模式,管理链表 { public: static MemoryManage* GetInStance() { if (_InStance == NULL) { _InStance = new MemoryManage(); } return _InStance; } void* __NEW(size_t size, string filename, int line);//申请空间 void __DELETE(void*ptr);//释放空间 void PPrint() { _infos.Print(); } private: MemoryManage() {} static MemoryManage* _InStance; List<MemoryBlockInfo>_infos; }; /*****************************************************************************************************/ //对于单个对象 template<class T> inline T* _NEW(size_t size, string filename, int line) { //对于自定义类型,会调用构造函数;但在这里对象已经产生,所以需要用new的定位表达式来调构造函数 return new((T*)MemoryManage::GetInStance()->__NEW(size, filename, line))T; } template<class T> inline void _DELETE(T*ptr)//释放空间 { ptr->~T();//对于自定义类型,会调用析构函数 MemoryManage::GetInStance()->__DELETE(ptr); } #define NEW(type) _NEW<type>(sizeof(type), __FILE__, __LINE__) #define DELETE(ptr) _DELETE(ptr) /****************************************************************************************************/ //对于对象数组 template<class T> inline T* _NEW_ARRAY(size_t num, string filename, int line) { //对于对象数组,在申请空间时,需多申请4个字节的空间,存储数组元素的个数,即有多少个对象 T*ptr = (T*)(MemoryManage::GetInStance()->__NEW(sizeof(T)*num + 4, filename, line)); *(int*)ptr = num; T*Retptr = (T*)((int*)ptr + 1); for (int i = 0; i <(int) num; i++) { new(&Retptr[i])T;//调用构造函数 } return ptr; } template<class T> inline void _DELETE_ARRAY(T*ptr) { int num = *(int*)ptr; T*Retptr = (T*)((int*)ptr + 1); for (int i = 0; i < num; i++) { Retptr[i].~T();//调用析构函数 } MemoryManage::GetInStance()->__DELETE(ptr); } #define NEW_ARRAY(type,num) _NEW_ARRAY<type>(num,__FILE__,__LINE__) #define DELETE_ARRAY(ptr) _DELETE_ARRAY(ptr) #endif //_MEM_H_ /****************************************************************************************************/
//MemoryBlockInfo.cpp
#include"MemoryBlockInfo.h" MemoryBlockInfo::MemoryBlockInfo(void*ptr, string filename, int line) :_ptr(ptr) , _filename(filename) , _line(line) {} bool MemoryBlockInfo::operator==(const MemoryBlockInfo&m) { return _ptr == m._ptr; } ostream& operator<<(ostream& out, MemoryBlockInfo&m) { out << "ptr:" << m._ptr << endl; out << "filename:" << m._filename << endl; out << "line:" << m._line << endl; return out; } void* MemoryManage::__NEW(size_t size, string filename, int line) { void*ptr = malloc(size); if (ptr) { _infos.PushBack(MemoryBlockInfo(ptr, filename, line)); } return ptr; } void MemoryManage::__DELETE(void*ptr) { if (ptr) { Node<MemoryBlockInfo>*del = _infos.Find(MemoryBlockInfo(ptr)); _infos.Remove(del); } free(ptr); }
#define _CRT_SECURE_NO_WARNINGS #include"MemoryBlockInfo.h" class String//自定义String类 { public: String(char* ptr = "") :_ptr(new char[strlen(ptr) + 1]) { cout << "String()" << endl; strcpy(_ptr, ptr); } ~String() { if (_ptr) { delete []_ptr; } cout << "~String()" << endl; } private: char* _ptr; }; void Test() { int*p1 = NEW(int); String*p2 = NEW(String); DELETE(p1); DELETE(p2); String*p3 = NEW_ARRAY(String,3); DELETE_ARRAY(p3); MemoryManage::GetInStance()->PPrint(); } MemoryManage* MemoryManage::_InStance = NULL;//初始化静态数据 int main() { Test(); system("pause"); return 0; }