通用C++内存池代码
来源:互联网 发布:响应式博客模板知乎 编辑:程序博客网 时间:2024/05/16 15:51
原理在这里http://blog.csdn.net/kevin_qing/article/details/608891
以前代码找不到了,重写一次。
加上了一些简单的错误检测代码。帮助调试内存问题。
初步代码,还未仔细检查,有bug请留言。
//type and macro#include <default.h>//debug 信息constboolDebugQMem=1;structQMemDebugInfo{uint32_tmask;uint32_tsize;byteguard[128-8];};template <bool flag, typename T, typename U>struct TypeSelectT{private: template<bool> struct In { typedef T Result; }; template<> struct In<false> { typedef U Result; };public: typedef typename In<flag>::Result Result;};//计算ln(x)/ln(y),向上转换为整形template <uint64_t x,uint64_t y>struct logT{protected: template <uint64_t x1> struct imp{ enum { next=(x1+y-1)/y, }; enum {Result=1+imp<next>::Result}; }; template <>struct imp<1>{ enum {Result=0}; };public: enum {Result=imp<x>::Result};};//x^ytemplate <uint64_t x,uint64_t y>struct powerT{protected: template <uint64_t y1> struct imp{ enum{ next=y1-1 }; enum{ Result=x*imp<next>::Result }; }; template<> struct imp<0>{ enum{ Result=1 }; };public: enum{ Result=imp<y>::Result };};//缓存表,template <uint64_t index>struct cacheCount{ //table<>未实现0,1,2,3,所以不允许<16b的对象编译通过,避免空间太小不能容纳调试信息。template <uint64_t>structtable;template <>struct table<4>{ enum{Result= 4096};};//16b -> 64ktemplate <>struct table<5>{ enum{Result= 4096};};//32b -> 128ktemplate <>struct table<6>{ enum{Result= 4096};};//64b -> 256ktemplate <>struct table<7>{ enum{Result= 4096};};//128b-> 512ktemplate <>struct table<8>{ enum{Result= 2048};};//256b-> 512ktemplate <>struct table<9>{ enum{Result= 2048};};//512b-> 1mtemplate <>struct table<10>{ enum{Result= 2048};};//1k -> 2mtemplate <>struct table<11>{ enum{Result= 2048};};//2k -> 4mtemplate <>struct table<12>{ enum{Result= 1024};};//4k -> 4mtemplate <>struct table<13>{ enum{Result= 1024};};//8k -> 8mtemplate <>struct table<14>{ enum{Result= 1024};};//16k -> 16m //更多的使用时添加template <>struct table<20>{ enum{Result= 4};};//1m -> 4mstructminCache{enum{Result=2};};enum{Result=TypeSelectT<index<20,table<logT<index,2>::Result>,minCache>::Result::Result };};//链表,用于可用空间回收structQMemLink{QMemLink*next;};classQMemTest;byte*QAlloc(size_t s){returnnew byte[s];}template <size_t size> class QFixAllocator{friendclassQMemTest;uint64_tusageBytes;uint64_tallocBytes;uint64_tpoolBytes;QMemLink*memPool;enum{sizeFix=powerT<2,logT<size,2>::Result>::Result};enum{caches=cacheCount<sizeFix>::Result};protected:QFixAllocator(){usageBytes=0;allocBytes=0;poolBytes=0;memPool=NULL;}public:void* alloc(size_t s){assert(s<=sizeFix);//避免new[]call到错误的allocator,host class应该使用单独版本的new[](),而不是默认调用new()QMemLink*r;if(memPool){r=memPool;memPool=memPool->next;poolBytes-=sizeFix;usageBytes+=s;returnr;}byte*p=QAlloc(sizeFix*caches);memPool=(QMemLink*)p;for(int i=1;i<caches;++i){r=(QMemLink*)p;p+=sizeFix;r->next=(QMemLink*)p;;}r->next=NULL;poolBytes+=(caches-1)*sizeFix;usageBytes+=s;allocBytes+=caches*sizeFix;returnp;}void free(void*p,size_t s){QMemLink*l=(QMemLink*)p;l->next=memPool;memPool=l;usageBytes-=s;poolBytes+=size;}voidstatus(uint64_t &u,uint64_t &a,uint64_t& p)const{u=usageBytes;a=allocBytes;p=poolBytes;}typedef QFixAllocator me;static me Instance;};typedefQFixAllocator<powerT<2,4>::Result>QFixAllocator_4;typedefQFixAllocator<powerT<2,5>::Result>QFixAllocator_5;typedefQFixAllocator<powerT<2,6>::Result>QFixAllocator_6;typedefQFixAllocator<powerT<2,7>::Result>QFixAllocator_7;typedefQFixAllocator<powerT<2,8>::Result>QFixAllocator_8;typedefQFixAllocator<powerT<2,9>::Result>QFixAllocator_9;typedefQFixAllocator<powerT<2,10>::Result>QFixAllocator_10;typedefQFixAllocator<powerT<2,11>::Result>QFixAllocator_11;typedefQFixAllocator<powerT<2,12>::Result>QFixAllocator_12;typedefQFixAllocator<powerT<2,13>::Result>QFixAllocator_13;typedefQFixAllocator<powerT<2,14>::Result>QFixAllocator_14;typedefQFixAllocator<powerT<2,15>::Result>QFixAllocator_15;typedefQFixAllocator<powerT<2,16>::Result>QFixAllocator_16;typedefQFixAllocator<powerT<2,17>::Result>QFixAllocator_17;typedefQFixAllocator<powerT<2,18>::Result>QFixAllocator_18;typedefQFixAllocator<powerT<2,19>::Result>QFixAllocator_19;typedefQFixAllocator<powerT<2,20>::Result>QFixAllocator_20;typedefQFixAllocator<powerT<2,21>::Result>QFixAllocator_21;QFixAllocator_10QFixAllocator_10::Instance;QFixAllocator_11QFixAllocator_11::Instance;QFixAllocator_12QFixAllocator_12::Instance;QFixAllocator_13QFixAllocator_13::Instance;QFixAllocator_14QFixAllocator_14::Instance;QFixAllocator_15QFixAllocator_15::Instance;QFixAllocator_16QFixAllocator_16::Instance;QFixAllocator_17QFixAllocator_17::Instance;QFixAllocator_18QFixAllocator_18::Instance;QFixAllocator_19QFixAllocator_19::Instance;QFixAllocator_20QFixAllocator_20::Instance;QFixAllocator_21QFixAllocator_21::Instance;template<class Host>classQMemImpl{public:void*operatornew(size_t size){returnQFixAllocator<powerT<2,logT<sizeof(Host),2>::Result>::Result>::Instance.alloc(size);}voidoperatordelete(void*p){returnQFixAllocator<powerT<2,logT<sizeof(Host),2>::Result>::Result>::Instance.free(p,sizeof(Host));}void*operatornew[](size_t size){size+=8;//x64 8字节对齐ULONGr,f;_BitScanReverse(&r,size);_BitScanReverse(&f,size);if(r!=f)//对齐++r;switch(r){case19://这里只处理了1m字节的分配{uint32_t *p=(uint32_t*)QFixAllocator_20::Instance.alloc(size);*p=19;//set mask++p;*p=size;return++p;}default:DebugBreak();}throw"bad alloc";}voidoperatordelete[](void*p){uint32_t*p32=(uint32_t*)p;p32-=2;switch(*p32){case19://这里只处理了1m字节的释放QFixAllocator_20::Instance.free(p32,*(p32+1));return;default:DebugBreak();}}};template<class Host>classQMemDebugImpl{public:void*operatornew(size_t size){QMemDebugInfo*p=(QMemDebugInfo*)QFixAllocator<powerT<2,logT<sizeof(Host)+sizeof(QMemDebugInfo),2>::Result>::Result>::Instance.alloc(size);memset(p->guard,0,sizeof(p->guard));p->mask=logT<sizeof(Host)+sizeof(QMemDebugInfo),2>::Result;p->mask|=0x12345600;p->size=size;return++p;}voidoperatordelete(void*p){QMemDebugInfo*pDebug=(QMemDebugInfo*)p;--pDebug;if((pDebug->mask&(~0xff))!=0x12345600){ //标志错,可能是乱用delete,new[]DebugBreak();}if(pDebug->size!=sizeof(Host)){//size错DebugBreak();}//其他检查returnQFixAllocator<powerT<2,logT<sizeof(Host)+sizeof(QMemDebugInfo),2>::Result>::Result>::Instance.free(pDebug,sizeof(Host));}void*operatornew[](size_t size){size+=sizeof(QMemDebugInfo);ULONGr,f;if(!_BitScanReverse(&r,size))DebugBreak();//size 0,不可能的情况_BitScanReverse(&f,size);if(r!=f)//对齐++r;QMemDebugInfo *p;switch(r){case19:p=(QMemDebugInfo*)QFixAllocator_20::Instance.alloc(size);p->mask=19;break;case20:p=(QMemDebugInfo*)QFixAllocator_21::Instance.alloc(size);p->mask=20;break;default:DebugBreak();}memset(p->guard,0,sizeof(p->guard));p->size=size;return++p;}voidoperatordelete[](void*p){QMemDebugInfo *pDebug=(QMemDebugInfo*)p;--pDebug;if(pDebug->mask&(~0xff)){ //标志错,可能是乱用delete[],newDebugBreak();}if(pDebug->size<sizeof(Host)){//size错DebugBreak();}ULONGr,f;_BitScanReverse(&r,pDebug->size);_BitScanReverse(&f,pDebug->size);if(r!=f)++r;if(pDebug->mask!=r)DebugBreak();switch(pDebug->mask){case19:QFixAllocator_20::Instance.free(pDebug,pDebug->size);return;case20:QFixAllocator_21::Instance.free(pDebug,pDebug->size);return;default:DebugBreak();}}};template<class Host>classQMemPool:public TypeSelectT<DebugQMem,QMemDebugImpl<Host>,QMemImpl<Host>>::Result{};classQMemTest:publicQMemPool<QMemTest>{chartmp[1000];};voidshowMemInfo(){uint64_tu,a,p;QFixAllocator_11::Instance.status(u,a,p);printf("_11 u=%I64u a=%I64u p=%I64u \n",u,a,p);QFixAllocator_20::Instance.status(u,a,p);printf("_20 u=%I64u a=%I64u p=%I64u \n",u,a,p);}void main(){QMemTest*pTest[4096];showMemInfo();for(int i=0;i<countof(pTest);++i){pTest[i]=newQMemTest;}printf("new\n");showMemInfo();for(int i=0;i<countof(pTest);++i){deletepTest[i];}printf("delete\n");showMemInfo();deletenewQMemTest[1024];printf("delete[] new[]\n");showMemInfo();}
- 通用C++内存池代码
- C-通用内存交换函数
- .NET 加密 通用代码(c#)
- 利用/dev/mem和mmap读写linux内存的通用C代码及原理
- 通用内存池
- nginx内存池代码分析[ngx_palloc.c]
- 嵌入式(标准C环境下)下通用的内存池的实现---C文件
- 嵌入式(标准C环境下)下通用的内存池的实现---前言
- 嵌入式(标准C环境下)下通用的内存池的实现---头文件
- 嵌入式(标准C环境下)下通用的内存池的实现---后记(使用)
- C代码检测内存泄漏
- c代码内存存放细节
- C代码的内存布局
- 通用基于TCP协议的C/S模型的代码
- 内存数据表和内存索引通用结构(基于C++) --Memory Table Interface Embed In Your Application
- 防止C代码内存泄露的方法
- C系代码内存处理优化分析
- 高质量的C代码.释放内存
- 互联网用户常见的9种心理特征
- 一个页面重构工程师眼中的“用户体验”
- Chromium 快捷键列表
- 养身
- 惶恐
- 通用C++内存池代码
- Web Service
- 使用9妹的注意事项
- 2.11 最近点对
- vmware Dos声卡驱动安装说明
- 《学习openCV》例程解析 ex_8_2 (轮廓)
- 一个malloc的crash问题
- 在Win2003系统远程桌面设置多连接数方法(转载)
- SQL查询递归