麒麟子

~~

导航

<2009年10月>
27282930123
45678910
11121314151617
18192021222324
25262728293031
1234567

统计

常用链接

留言簿(12)

随笔分类

随笔档案

Friends

WebSites

积分与排名

最新随笔

最新评论

阅读排行榜

评论排行榜

某内存池中的指针用法

内存池实现有许多种,各有不同的优缺点。

这里不是主要说内存池,只是觉得这个内存池中的指针用得很飘逸!

 

 1template <class T,int AllocSize = 50>   
 2class MemPool   
 3{   
 4public:   
 5    static void* operator new(size_t allocLength)   
 6    {   
 7        if(!mStartPotinter)   
 8        {   
 9            MyAlloc();   
10        }
   
11        //将当前指向空闲内存起始地址作为反回地址   
12        unsigned char* p = mStartPotinter;   
13        //取出空闲区域前4字节的值,赋值给空闲地址   
14        //因为前四字节中存放了下一个BLOCK的地址   
15        mStartPotinter = *(unsigned char**)mStartPotinter;   
16        return p;   
17    }
   
18  
19    static void operator delete(void* deleteP)   
20    {   
21//      assert(deletePointer);   
22        *(unsigned char**)deleteP = mStartPotinter;   
23        mStartPotinter = (unsigned char*)deleteP;   
24    }
   
25  
26    static void MyAlloc()   
27    {   
28        //预分配内存   
29        mStartPotinter = new unsigned char[sizeof(T)*AllocSize];   
30        //构造BLOCK之间的关系    
31        //每个BLOCK的前4BYTE存放了下一个BLOCK的地址   
32        unsigned char** next = (unsigned char**)mStartPotinter;   
33        unsigned char* p = mStartPotinter;   
34  
35        for(int i = 0; i< AllocSize;++i)   
36        {   
37            p +=sizeof(T);//步进   
38            *next = p;//赋值   
39            next = (unsigned char**)p;//步进   
40        }
   
41        *next = NULL;   
42    }
   
43  
44    static unsigned char* mStartPotinter;   
45}
;   
46  
47template <class T,int AllocSize>   
48unsigned char* MemPool<T,AllocSize>::mStartPotinter = NULL;  
49
50
51本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/wqjqepr/archive/2010/05/03/5552322.aspx

 

 

简单提示一下: unsigned char** next = (unsigned char**)mStartPotinter;

mStartPotinter作为二维指针的时候,相当于是一系列的unsigned char* [].

对于第一个 *next 相当于(unsigned char*)mStartPointer[0].

第二个相当于(unsigned char*)mStartPointer[sizeof(T)*1];

第三个相当于(unsigned char*)mStartPointer[sizeof(T)*2];

所以,构造BLOCK之间关系的时候,也可以写成

 

1for(int i = 0; i< AllocSize;++i)   
2{   
3 p +=sizeof(T);//步进   
4 unsigned char* pp = (unsigned char*)(p[sizeof(T)*i]);   
5 pp = p;//赋值   
6}
 

 

 

不想多解释了,累。估计多看几分种啥都明白了!

 

 

posted on 2010-05-03 18:33 麒麟子 阅读(1936) 评论(11)  编辑 收藏 引用 所属分类: Programming

评论

# re: 某内存池中的指针用法 2010-05-04 09:02 jmchxy

这个使用非常的正常, 基本上内存池都是这样的结构。或者为了可读性使用一个 类似下面的union 。

union BLOCK
{
BLOCK* next;
unsigned char data[BLOCKSIZE];
};

指针的强制类型转换和0字节的数组在Win32 API中广泛使用着  回复  更多评论   

# re: 某内存池中的指针用法 2010-05-04 09:32 小时候可靓了

嗯,是的! 谢谢讲解!  回复  更多评论   

# re: 某内存池中的指针用法 2010-05-04 09:33 小时候可靓了

@jmchxy
这样行么?
union BLOCK
{
unsigned char* next;
unsigned char data[BLOCKSIZE];
};  回复  更多评论   

# re: 某内存池中的指针用法 2010-05-04 10:55 zuhd

@小时候可靓了
我个人觉得
union BLOCK
{
DWORD next;
unsigned char data[BLOCKSIZE];
};
这样写都行,只要能把这个指针的地址保存到 data的前4个字节,后面自己做强制转换就好了,不过BLOCK* next这样的格式是科学的,用void* 或DWORD来声明指针,然后用*(T*)这样的格式去取,就太不和谐了
  回复  更多评论   

# re: 某内存池中的指针用法 2010-05-04 11:33 丽可酷

谢谢讲解  回复  更多评论   

# re: 某内存池中的指针用法 2010-05-04 12:53 小时候可靓了

@zuhd
嗯,谢谢,我早上脑残了。哈哈  回复  更多评论   

# re: 某内存池中的指针用法 2010-05-04 17:44 Kevin Lynx

就是把一整块内存分成多块,利用未使用位置串联下这些块。很多代码都会涉及到这种用法。  回复  更多评论   

# re: 某内存池中的指针用法 2010-05-04 18:58 小时候可靓了

@Kevin Lynx
嗯,就是这样的!!!  回复  更多评论   

# re: 某内存池中的指针用法 2010-05-04 18:58 小时候可靓了

不知道还有其它方式么!!  回复  更多评论   

# re: 某内存池中的指针用法 2010-05-05 09:32 lymons

很棒,学习了。

不过,这对单个block的分配是个很好的解决方案,
但是要是分配多个block呢?
在重载delete操作符的函数中,是没有办法知道要本次要删除的内存
到底有多少个块,也就没有办法维护这些block中的地址表。当然,
除非把block数作为参数传进去,但这样的话,就造成了用户
的麻烦,用户在删除分配给自己的内存的时候还必须记得这块内存里
的block的数目,万一写错了,后果不堪设想。  回复  更多评论   

# re: 某内存池中的指针用法 2010-05-05 13:39 wjn

我觉得这种方法有一个限制:sizeof(T) >= sizeof(指针)
用union那种就没事了,仅仅是这样做空间上划不来而已  回复  更多评论   


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理