#include <iostream>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <list>
#include <malloc.h>
using namespace std;
class String
{ public:
String():ptr(new char[1])
{
//cout<<"String()"<<endl;
ptr[0]=‘\0‘;
}
~String()
{
if(ptr){
delete ptr;
ptr = NULL;
}
}
String(const char *p):ptr(new char[strlen(p)+1])
{
strcpy(ptr,p);
}
void Printf()
{
if(ptr)
cout<<ptr<<endl;
}
String(const String& s):ptr(new char[strlen(s.ptr)+1])
{
strcpy(ptr,s.ptr);
}
String& operator = (const String &s)
{
if(this!=&s)
{
if(ptr)delete []ptr;
ptr = (char *)malloc(strlen(s.ptr)+1);
strcpy(ptr,s.ptr);
}
}
char& operator [](int size)
{
return ptr[size];
}
private:
char *ptr;
};
///测试类
struct Node
{
void *_P;
size_t _Line;
char *_Filename;
size_t _Size;
Node(void *q = NULL,size_t len = size_t(), const char *name="",int d=int()):_P(q), _Line(len),_Filename(new char[strlen(name)+1]),_Size(d)
{
strcpy(_Filename,name);
}
};
#define ALLOC(type) (_ALLOC(sizeof(type),__FILE__,__LINE__,type()))
#define ALLOCARRAY(type,size) (__ALLOC(sizeof(type),size,__FILE__,__LINE__,type()))
//定义宏是不能进行重载的,刚才遇到这个问题了,记录一下,type是一个类型.
list<Node> mlist;//调用stl的一个链表保存.
ostream& operator <<(ostream& os,const Node &node)//重载内存泄漏输出信息。
{
cout<<node._P<<"\t";
cout<<node._Line<<"\t";
cout<<node._Filename<<"\t";
cout<<node._Size<<"\t";
cout<<endl;
}
///////////////////////////////////////////////
struct _false
{
bool IsPod()
{
return false;//另一种方式的类型选择.
}
};
struct _true
{
bool IsPod()
{
return true;
}
};//萃取.
template<typename type>//范化
class triast
{
public:
typedef _false _ISPOD_ ;
};
template<>
class triast<int>//特化
{
public:
typedef _true _ISPOD_;
};
template<>//特化。
class triast<char>
{
public:
typedef _true _ISPOD_;
};
template<>
class triast<double>
{
public:
typedef _true _ISPOD_;
};
template<>
class triast<long>
{
public:
typedef _true _ISPOD_;
};
template<>
class triast<short>
{
public:
typedef _true _ISPOD_;
};
/////////////////////////////////////////////////
static void DELETEARRAY(void *p,int size)
{
list<Node> :: iterator it;
list<Node> :: iterator itSave;
it=mlist.begin();
while(it->_P!=p)
{
it++;
}
it--;
for(int i=0;i<size+1;i++)
{
itSave = it++;//必须保存itSave,让it++,再删除itSave,不然当我们删除it之后,再it++,
mlist.erase(itSave);//会报错,因为it已经不存在了.
}
};
template<typename type>
static void* __ALLOC(int size,int len,const char *_file_,int _line_,type s1)
{
//这是非STL那种搞法。
typedef typename triast<type> :: _ISPOD_ ispod;
void *p = malloc(size*len+4);
(*((int *)p))=len;
Node node(p,size,"0",_line_);//cookie值用“0”标记,打印的时候进行选择.
mlist.push_back(node);
p = (int *)p+1;
if(!ispod().IsPod())//构造.
{
type *q = (type *)p;
for(int i=0;i<len;i++)
{
Node node(q,size,_file_,_line_);
mlist.push_back(node);
new(q)type();
q+=1;
}
return p;
}
else
{
type *q = (type *)p;
for(int i=0;i<len;i++)
{
Node node(p,size,_file_,_line_);
mlist.push_back(node);
q+=1;
}
return p;
}
}
///////////////////////////////////////////////////////////////////////////
template<typename type>
static void* _ALLOC(int size,const char *_file_,int _line_,_true,type s1)
{ //不需要调用构造函数的赖皮空间的方式如int *,char *
void *p = malloc(size);
Node node(p,size,_file_,_line_);
mlist.push_back(node);
return p;
}
template<typename type>
static void* _ALLOC(int size,const char *_file_,int _line_,_false,type s1)
{
//需要调用构造函数的靠皮空间的方式如:String s();
void *p = malloc(size);
Node node(p,size,_file_,_line_);
mlist.push_back(node);
new(p)type();
return p;
}
template<typename type>
static void* _ALLOC(int size,const char *_file_,int _line_,type s1)//STL的那种搞法.
{
typedef typename triast<type> :: _ISPOD_ ispod;
return _ALLOC(size,_file_,_line_,ispod(),s1);
}
static void Printf()
{
list<Node> :: iterator it;
it = mlist.begin();
while(it!=mlist.end())
{
if(strcmp(it->_Filename,"0"))
cout<<*it<<"\t";
++it;
}
}
template<typename type>
static void _DELETE(type *p,_true)
{
list<Node> :: iterator it;
it = mlist.begin();
while(1)
{
if(it->_P==p){
mlist.erase(it);
break;
}
it++;
}
}
template<typename type>
static void _DELETE(type *p,_false)
{
list<Node> :: iterator it;
it = mlist.begin();
p->~type();
while(1)
{
if(it->_P==p){
mlist.erase(it);
break;
}
it++;
}
}
template<typename type>
static void DELETE(type *p)//这里就需要类型萃取,自动判别P的类型,看是否需要调用析构函数。
{
typedef typename triast<type> :: _ISPOD_ ispod;
_DELETE(p,ispod());
}
int main()
{
//String *s = (String *)ALLOC(String);
//int *a = (int *)ALLOC(sizeof(int)int);
//DELETE(s);
//int *b = (int *)ALLOC(int);
//int *p = (int *)ALLOCARRAY(int,2);
String *s = (String *)ALLOCARRAY(String,3);
// DELETEARRAY(s,3);
// s[0].Printf();
// s[1].Printf();
// s[2].Printf();
//ALLOCARRY(int,2);
Printf();
//traits(s);//萃取测试.
return 0;
}
让我们一起来实现一个内存管理工具第二章(类型,cookie信息,构造,数组)
原文地址:http://blog.csdn.net/liuhuiyan_2014/article/details/46124997