首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > C++ >

最近心血来潮想做个内存池类,代码贴出求批评指正!解决办法

2012-02-13 
最近心血来潮想做个内存池类,代码贴出求批评指正!自己想实现一个简单的内存池,但是构造的时候有不知道如何

最近心血来潮想做个内存池类,代码贴出求批评指正!
自己想实现一个简单的内存池,但是构造的时候有不知道如何下手,下面贴出我理解和构造的简单的类定义与部分实现,望高手指出错误并且给出修改意见,谢谢!
--------------------
CMemPool.h

#ifndef   __CMEMPOOL_H__
#define   __CMEMPOOL_H__

#include <string>
using   namespace   std;

const   int   INTDEFBLOCKSIZE   =   8;     ///内存扩容与收缩的数量级

struct   StringLink                         ////定义字符型内存的链表结构
{
StringLink   *   next;
bool               m_bIsUse;
string           m_strDataName;
string           m_strDataValue;
};

struct   IntLink                               ////定义数值型内存的链表结构
{
IntLink         *   next;
bool               m_bIsUse;
string           m_strDataName;
int                 m_intDataValue;
};

class   CMemPool{
protected:
int       m_intSizeString;                       ///字符内存链表的长度
int       m_intSizeInt;                             ///数值内存链表的长度
int       m_intSizeStringFree;               ///字符内存空闲结点数量
int       m_intSizeIntFree;                     ///数值内存空闲结点数量
bool     m_bMutex;                                     ///内存池的锁变量
StringLink   *   m_pStringLinkFree;     ///始终指向字符内存中空闲结点的指针
StringLink   *   m_pStringLinkHead;     ///指向字符内存链表头结点的指针  
IntLink   *   m_pIntLinkFree;                 ///始终指向数值内存中空闲结点的指针
IntLink   *   m_pIntLinkHead;                 ///指向数值内存链表头结点的指针

public:
////构造函数,执行2种类型的内存链表的构造与初始化,初始化成员变量的值,
////执行过程期间为锁定状态,执行完毕解锁。
CMemPool(void);

////查找一个字符内存的空闲结点,使用找到的空闲结点
virtual   int   UseStringData(string,   string)   =   0;

////查找一个数值内存的空闲结点,使用找到的空闲结点
virtual   int   UseIntData(string,   int)   =   0;

////放弃对应名称字符型结点的使用,使之成为空闲结点
virtual   int   UnuseStringData(string)   =   0;

////放弃对应名称数值型结点的使用,使之成为空闲结点
virtual   int   UnuseIntData(string)   =   0;

////取得对应名称字符型结点内储存的值
virtual   int   GetStringData(string,   string&)   =   0;

////取得对应名称数值型结点内储存的值
virtual   int   GetIntData(string,   int&)   =   0;

////析构函数,功能与构造函数相反
~CMemPool(void);
protected:
////当字符型内存链表的空闲结点不够使用时扩展字符型内存链表的长度
virtual   int   ExtendStringLink(void)   =   0;

////当数值型内存链表的空闲结点不够使用时扩展数值型内存链表的长度
virtual   int   ExtendIntLink(void)   =   0;

////当字符型内存链表的空闲结点过多是收缩字符型内存链表
virtual   int   UnextendStringLink(void)   =   0;

////当数值型内存链表的空闲结点过多时收缩数值型内存链表
virtual   int   UnextendIntLink(void)   =   0;



////在字符型内存链表中查找相应名称的结点
virtual   int   FindStringData(string,   StringLink   *)   =   0;

////在数值型内存链表中查找相应名称的结点
virtual   int   FindIntData(string,   IntLink   *)   =   0;
};

#endif


----------------------------
CMemPool.cpp

#include   "CMemPool.h "

CMemPool::CMemPool(void)
{
m_bMutex   =   false;         ///加琐

m_intSizeString   =   INTDEFBLOCKSIZE;
m_intSizeInt   =   INTDEFBLOCKSIZE;
m_intSizeStringFree   =   INTDEFBLOCKSIZE;
m_intSizeIntFree   =   INTDEFBLOCKSIZE;
m_pStringLinkFree   =   0;
m_pStringLinkHead   =   0;
m_pIntLinkFree   =   0;
m_pIntLinkHead   =   0;

////构造字符内存链表
StringLink   *   pOldStringNode   =   0;   ///记录前一个节点地址。
for(int   intIndexTem   =   0;   intIndexTem   <   m_intSizeString   -   1;   ++intIndexTem)
{
StringLink   *   pNewCreateStringNode   =   0;
pNewCreateStringNode   =   new   StringLink;

//////?防止new申请内存失败,保证申请内存成功!
while(pNewCreateStringNode=0)
{
pNewCreateStringNode   =   new   StringLink;
}
//////?end

/////清空新申请内存中的垃圾数据
pNewCreateStringNode   -> next   =   0;
pNewCreateStringNode   -> m_bIsUse   =   false;
pNewCreateStringNode   -> m_strDataName.erase();
pNewCreateStringNode   -> m_strDataValue.erase();


if(m_pStringLinkHead   =   0)
m_pStringLinkHead   =   pNewCreateStringNode;
if(m_pStringLinkFree   =   0)
m_pStringLinkFree   =   pNewCreateStringNode;

////建立实际字符链表try{
if(pOldStringNode   =   0)
pOldStringNode   =   pNewCreateStringNode;
else
{
pOldStringNode   ->   next   =   pNewCreateStringNode;
pOldStringNode   =   pNewCreateStringNode;
}
///}catch()

pNewCreateStringNode   =   NULL;
}
        pOldStringNode   =   NULL;

////构造整数内存链表
IntLink   *   pOldIntNode   =   0;   ///记录前一个节点地址。
for(intIndexTem   =   0;   intIndexTem   <   m_intSizeInt   -   1;   ++intIndexTem)
{
IntLink   *   pNewCreateIntNode   =   0;
pNewCreateIntNode   =   new   IntLink;

/////?保证new申请内存成功
while(pNewCreateIntNode   =   0)
{
pNewCreateIntNode   =   new   IntLink;
}
////?end


/////清空新申请内存中的垃圾数据
pNewCreateIntNode   -> next   =0;
pNewCreateIntNode   -> m_bIsUse   =   false;
pNewCreateIntNode   -> m_strDataName.erase();
pNewCreateIntNode   -> m_intDataValue   =   0   ;


if(m_pIntLinkHead   =   0)
m_pIntLinkHead   =   pNewCreateIntNode;
if(m_pIntLinkFree   =   0)
m_pIntLinkFree   =   pNewCreateIntNode;

////建立实际整数链表try{
if(pOldIntNode   =   0)
pOldIntNode   =   pNewCreateIntNode;
else
{
pOldIntNode   ->   next   =   pNewCreateIntNode;
pOldIntNode   =   pNewCreateIntNode;


}
///}catch()

pNewCreateIntNode   =   NULL;
}
        pOldIntNode   =   NULL;

m_bMutex   =   true;         ///解琐
}


CMemPool::~CMemPool(void)
{
m_bMutex   =   false;

m_pIntLinkFree   =   NULL;
m_pStringLinkFree   =   NULL;

IntLink   *   pNextIntNode   =   0;
for(int   intIndexTem   =   0;   intIndexTem   <   m_intSizeInt   -   1;   ++intIndexTem)
{

pNextIntNode   =   m_pIntLinkHead   ->   next;
delete   m_pIntLinkHead;
m_pIntLinkHead   =   pNextIntNode;

}
pNextIntNode   =   NULL;

StringLink   *   pNextStringNode   =   0;
for(intIndexTem   =   0;   intIndexTem   <   m_intSizeString   -   1;   ++intIndexTem)
{

pNextStringNode   =   m_pStringLinkHead   ->   next;
delete   m_pStringLinkHead;
m_pStringLinkHead   =   pNextStringNode;

}
pNextStringNode   =   NULL;

m_pStringLinkHead   =   NULL;
m_pIntLinkHead   =   NULL;

m_intSizeString   =   0;
m_intSizeInt   =   0;
m_intSizeStringFree   =   0;
m_intSizeIntFree   =   0;

m_bMutex   =   true;
}

[解决办法]
建议找《STL源码剖析》或者《Modern C++ Design》参考它们的内存池。
boost::pool也可以参考参考。
[解决办法]
这个为什么不用一个template来实现呢?
这样就不用对每种类型都写一个内存池了
我在项目中曾经也写过一个回收站,但是当时用的是void*的方法,现在学了template之后感觉如果用template才是正道。
[解决办法]
感觉不错啊,完善几点就更好了:
1、考虑可重入。
2、可以将错误检测也放进去,比如上溢和下溢的检测、释放未分配的内存检测等,可以更方便的定位问题。
3、建议不要零碎的分配链表节点,防止出现碎片。
[解决办法]
写的不错, 可惜不是template.
你这个是两个链表, 没必要.
看看winx的网站吧

热点排行