使用c++的auto_ptr建立通用内存自动回收机制

最近在研究c++的内存自动回收方式,发现auto_ptr并不能自动回收数组内存,给内存管理带来一定的麻烦,因而为了解决此问题,研究得到可以使用数据结构与对象的方式进行改造,以实现动态内存数组的回收,以下为实现的代码,实际测试中并没有发现存在内存增长的情况,可以作为参考:

#include <wtypes.h> #include <windef.h> #include <winbase.h> #include <memory>

#include <iostream> #include <stdio.h> #include <string> #include <fstream> #include <vector> using namespace std;

class CData; typedef void (*CDATARELEASE)(CData* pthis); //动态分析内存自动回收处理类 class CData { public : template<typename T> static void vCDataRelease(CData* pthis) { cout<<"vCDataRelease call begin <<"<<typeid(T).name()<<endl; if (NULL != pthis->pPoint) { cout<<"vCDataRelease point ok! <<"<<endl; if(pthis->lNum>1) delete[] (T*)pthis->pPoint; else if(pthis->lNum==1) delete (T*)pthis->pPoint; } cout<<"vCDataRelease call end >>>"<<endl; } public: CData() { pPoint = NULL; lNum = 0; pRelease = NULL; } CData(void* pParam,long nNum,CDATARELEASE pFun) { pPoint = pParam; lNum = nNum; pRelease = pFun; } virtual ~CData() { if(pRelease==NULL) { if (NULL != pPoint) { if(lNum>1) delete[] pPoint; else if(lNum==1) delete pPoint; } } else pRelease(this); pPoint = NULL; } protected: public: void* pPoint; long lNum; //注意:这里为元素个数,并不是字节数,如class A时为1,class A[4]时为4 CDATARELEASE pRelease; };

//数据块节点定义 typedef struct _tDataBlock { _tDataBlock() { pPrev = NULL; pNext = NULL; } _tDataBlock* pPrev; _tDataBlock* pNext; auto_ptr<CData> pdata; //请注意 auto_ptr 所有权会转换,请注意使用规则 long nDataByteSize; }tDataBlock;

class myclass { public: myclass() { cout<<"myclass begin <<"<<endl; pbuffer = new char[1024*3]; } ~myclass() { cout<<"myclass end >>>>>>"<<endl; delete[] pbuffer; } private: char* pbuffer; }; int main() { //test class and void* int i = 0; for(i=0;i<100000;i++) { cout<<"new myclass begin....."<<i<<endl; Sleep(1000); { long l_nNum = 3; myclass* l_ptestmem = new myclass[l_nNum]; auto_ptr<CData> l_cmdptr(new CData(l_ptestmem,l_nNum,CData::vCDataRelease<myclass>)); tDataBlock l_tDataBlock; l_tDataBlock.pdata = l_cmdptr; l_tDataBlock.nDataByteSize = l_nNum*sizeof(myclass); cout<<"delete myclass begin....."<<endl; //Sleep(10000); } cout<<"delete myclass end....."<<endl; //Sleep(10000); cout<<"new char begin....."<<endl; { long l_nNum = 1024*300; char* l_ptestmem = new char[l_nNum]; auto_ptr<CData> l_cmdptr(new CData(l_ptestmem,l_nNum,CData::vCDataRelease<char>)); tDataBlock l_tDataBlock; l_tDataBlock.pdata = l_cmdptr; l_tDataBlock.nDataByteSize = l_nNum*sizeof(char); cout<<"delete char begin....."<<endl; //Sleep(10000); } cout<<"delete char end....."<<endl; //Sleep(10000); cout<<"all end....."<<endl; } return 0; }

若有什么问题,请评论。

PS:值得注意的是:void* point指针指向的数组,如果不使用明确的类型进行delete时,会仅delete成功1个“对象”,因此会带来内存泄漏,但此处使用了模板函数解决了此问题。

经验分享 程序员 微信小程序 职场和发展