c--内存池设计-学位论文

上传人:桔**** 文档编号:511781469 上传时间:2023-12-17 格式:DOC 页数:20 大小:550KB
返回 下载 相关 举报
c--内存池设计-学位论文_第1页
第1页 / 共20页
c--内存池设计-学位论文_第2页
第2页 / 共20页
c--内存池设计-学位论文_第3页
第3页 / 共20页
c--内存池设计-学位论文_第4页
第4页 / 共20页
c--内存池设计-学位论文_第5页
第5页 / 共20页
点击查看更多>>
资源描述

《c--内存池设计-学位论文》由会员分享,可在线阅读,更多相关《c--内存池设计-学位论文(20页珍藏版)》请在金锄头文库上搜索。

1、C+内存池设计在项目中进程要对变量和对象分配空间,由于频繁的使用new和delete很消耗程序的运行时间,而且容易产生各种内存泄露,内存释放错误等问题。为此,需要设计一个通用的内存池来完成相关的分配和释放的工作。建立内存池:首先向系统申请一块内存,这块内存的大小由使用者根据需要设置初始内存大小。 定义一个如下面代码所示的双向链表,将从系统分配的内存分为若干块。使用双向链表方便指针向前和向后遍历查找。链表中*Data指向了系统分配的内存,pUser使用二级指针保存了内存申请者的地址,方便以后系统内存块更改,改变申请者的指向。后面会详细介绍。将双向链表指向指向内存如下所示:假设内存池初始块数为4块

2、,每块的大小为100个字节,则向系统申请400个字节的内存块,每块的大小为100字节。之后使用双向链表DATA指针指向内存块,每个指针能分配的大小如图所示从大到小递减。对象内存分配:对内存的链表指针分配好后,用户可以使用内存池进行内存分配,对于用户的内存分配有两种情况,一种是在现有的内存池中能找到合适的内存块,另一种情况是现有内的内存池没有足够的内存块来分配,需要重新向系统申请内存来满足用户的需求。下面分别就这两种内存分配情况进行说明:情况1内存池有足够的内存块进行分配 假设用户申请了240个字节的内存空间,内存池现在有四个内存块空闲,每个内存块的大小为100字节,那么内存池将会给用户取整分配

3、三个内存块。如上图所示,并将指向400内存块的指针的DATE返回给用户使用。情况2内存池没有足够的内存块进行分配接着上图,假设用户现在要接着分别300字节的内存空间,现有内存池的大小已经不能满足,因此需要扩大现有的内存池使用大小。考虑到由于分配给用户的内存空间必须要是连续的内存块,因此这个连续的内存块越大,能分配给用户的内存就多。因此使用C语言的realloc函数来满足要求。函数简介原型:extern void *realloc(void *mem_address, unsigned int newsize);语法:指针名=(数据类型*)realloc(要改变内存大小的指针名,新的大小)。/新

4、的大小一定要大于原来的大小,不然的话会导致数据丢失!头文件:#include 有些编译器需要#include ,在TC2.0中可以使用alloc.h头文件功能:先判断当前的指针是否有足够的连续空间,如果有,扩大mem_address指向的地址,并且将mem_address返回,如果空间不够,先按照newsize指定的大小分配空间,将原有数据从头到尾拷贝到新分配的内存区域,而后释放原来mem_address所指内存区域(注意:原来指针是自动释放,不需要使用free),同时返回新分配的内存区域的首地址。即重新分配存储器块的地址。返回值:如果重新分配成功则返回指向被分配内存的指针,否则返回空指针NU

5、LL。由realloc函数定义可知,新分配的内存空间可能是在原有的内存基础上扩充,还有可能是在另外的一个地方新开辟一块内存。无论哪种情况多要对新加的内存进行指针指向分配。并且对于第二种情况,会出现的问题是原有的指针全都失效。因为原有指向的内存已经不存在了,因此指向它的指针将失效,原有分配的对象也将失效。为了解决这个问题,在新分配内存后需要重定向原有的指针,并且使用二级指针改变已经分配了对象的地址的指向,使它指向新内存。重定向原有内存的指针的指向,和已经分配了内存的对象的指向。对象释放内存:假如先前的申请了250个字节分配了三个内存块的用户释放了内存,这时链表指针向后查找直到找到第一个被使用的内

6、存块,或链表结尾。之后在先前查找直到找到前面第一个被使用的内存块或者是头指针,之后更新这个区间段内存块的大小。释放内存池:首先释放向系统申请的内存块,之后在清空所有的双向链表。释放向系统申请的内存释放双向链表。后续改进:1, 需要对多线程的支持,目前的内存池还只能在单线程的环境下运行。2, 如果之前得到内存的对象,在新内存分配前有指针复制操作,原有对象可以通过保存的指针地址进行重定向,但是之前分别的对象不能保证。引进对于分配的对象尽量不要使用指针复制。如果一定需要这么做,那就在每次使用前,在重定向一下。重新进行一次复制操作(保险起见,不知道我的表述是否清楚明白)。源代码:头文件链表节点的定义#

7、include#include#include#include using namespace std;namespace MemePooltypedef unsigned char EigthByte;/内存池的默认大小和分配节点的默认大小static const size_t DEFAULTMEMEPOOLSIZE = 1000;static const size_t DEFAULTMEMENODESIZE = 100;/内存初始分配内容 二进制位1111 1111static const int NEW_ALLOCATED_MEMORY_CONTENT = 0xFF;/内存分配节点(双向

8、链表)typedef struct TMemeNode/指向前一节点TMemeNode *first;/指向后一节点TMemeNode *next;/节点大小size_t idataSize;/节点是否被使用bool isUsed;/分配的节点的后一节点TMemeNode *pEndNode;/记录内存池分配的首地址bool isMemeBegin;/保存分配的内存地址EigthByte *Data ;/使用者对象的地址void *pUser; TMemeLinkNode;内存池实现:namespace MemePool/内存池的实现 作者邮箱class CMemePoolpublic:/线程

9、池构造函数CMemePool(const size_t &sInitialMemoryPoolSize = DEFAULTMEMEPOOLSIZE,const size_t &sMemoryChunkSize = DEFAULTMEMENODESIZE);CMemePool();/分配内存void *GetMemeroy(void *p,const size_t &sSize);/释放分配内存void FreeAllocMemeroy(void *p,const size_t &sSize);/释放内存池所有内存void FreeAllMemeroy();/展示内存池的使用情况void Sho

10、wTheMemePoolStatue();/获取错误信息void GetErrorInfo();private: /禁止复制与构造,要传递就用引用吧 CMemePool(CMemePool *tCMemePool); CMemePool& operator =(CMemePool &tCMemePool); void AllocPoolMemeroy(); void CalLinkNodeNum(); void CalMemeSize(); void LinkMemeryToNode(EigthByte *PAlloc); void UpdateLinkNodeSize(TMemeNode *

11、PNode); void CalNeetLinkNumber(const size_t &sSize); void* FindMemeNode(const size_t &sSize); TMemeNode * SearchAllocNode(void *p); void CleanAllMemeDate(); void CleatAllLinkNode();void ResetLinkToMemery(); /双向链表的头节点 TMemeLinkNode *m_Head; /双向链表的当前节点 TMemeLinkNode *m_Current; /双向链表的最后节点 TMemeLinkNod

12、e *m_LastNode; EigthByte *m_PAlloc; /保存第一次运行头地址 bool m_isFirst; /内存块分配数目 size_t m_Number;/内存块总的数目 size_t m_AllNumber; /每一个内存块的大小 size_t m_MemLinkSize; /内存池分配的大小 size_t m_MemePollSize; /内存块总分配大小 size_t m_AllAloctsize; /内存池使用的大小 size_t m_MemePoolUseSize; /内存池空闲的大小 size_t m_MemePoolFreeSize; /分配了多少个对象

13、size_t m_iUseObject; /保存错误信息 string m_sError; /保存请求分配内存用户信息 void *m_User;/-/recalloc分配新内存后,之前指向旧内存的指针就失效了/需要重新定位,之前分配对象的指向也要重新定位namespace MemePool/* 内存池构造函数 by 风清扬song 13-07-28*/CMemePool:CMemePool(const size_t &sInitialMemoryPoolSize,const size_t &sMemoryChunkSize)/初始化内存池的大小m_MemePollSize = sInitialMemoryPoolSize;/初始化每个内存块的大小m_MemLinkSize = sMemoryChunkSize;/初始化一些参数m_MemePoolFreeSize =

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 建筑/环境 > 施工组织

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号