ImageVerifierCode 换一换
格式:DOC , 页数:20 ,大小:550KB ,
资源ID:2180777      下载积分:10 金币
快捷注册下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

开通VIP
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.zixin.com.cn/docdown/2180777.html】到电脑端继续下载(重复下载【60天内】不扣币)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

开通VIP折扣优惠下载文档

            查看会员权益                  [ 下载后找不到文档?]

填表反馈(24小时):  下载求助     关注领币    退款申请

开具发票请登录PC端进行申请

   平台协调中心        【在线客服】        免费申请共赢上传

权利声明

1、咨信平台为文档C2C交易模式,即用户上传的文档直接被用户下载,收益归上传人(含作者)所有;本站仅是提供信息存储空间和展示预览,仅对用户上传内容的表现方式做保护处理,对上载内容不做任何修改或编辑。所展示的作品文档包括内容和图片全部来源于网络用户和作者上传投稿,我们不确定上传用户享有完全著作权,根据《信息网络传播权保护条例》,如果侵犯了您的版权、权益或隐私,请联系我们,核实后会尽快下架及时删除,并可随时和客服了解处理情况,尊重保护知识产权我们共同努力。
2、文档的总页数、文档格式和文档大小以系统显示为准(内容中显示的页数不一定正确),网站客服只以系统显示的页数、文件格式、文档大小作为仲裁依据,个别因单元格分列造成显示页码不一将协商解决,平台无法对文档的真实性、完整性、权威性、准确性、专业性及其观点立场做任何保证或承诺,下载前须认真查看,确认无误后再购买,务必慎重购买;若有违法违纪将进行移交司法处理,若涉侵权平台将进行基本处罚并下架。
3、本站所有内容均由用户上传,付费前请自行鉴别,如您付费,意味着您已接受本站规则且自行承担风险,本站不进行额外附加服务,虚拟产品一经售出概不退款(未进行购买下载可退充值款),文档一经付费(服务费)、不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
4、如你看到网页展示的文档有www.zixin.com.cn水印,是因预览和防盗链等技术需要对页面进行转换压缩成图而已,我们并不对上传的文档进行任何编辑或修改,文档下载后都不会有水印标识(原文档上传前个别存留的除外),下载后原文更清晰;试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓;PPT和DOC文档可被视为“模板”,允许上传人保留章节、目录结构的情况下删减部份的内容;PDF文档不管是原文档转换或图片扫描而得,本站不作要求视为允许,下载前可先查看【教您几个在下载文档中可以更好的避免被坑】。
5、本文档所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用;网站提供的党政主题相关内容(国旗、国徽、党徽--等)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。
6、文档遇到问题,请及时联系平台进行协调解决,联系【微信客服】、【QQ客服】,若有其他问题请点击或扫码反馈【服务填表】;文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“【版权申诉】”,意见反馈和侵权处理邮箱:1219186828@qq.com;也可以拔打客服电话:0574-28810668;投诉电话:18658249818。

注意事项

本文(c--内存池设计-学位论文.doc)为本站上传会员【w****g】主动上传,咨信网仅是提供信息存储空间和展示预览,仅对用户上传内容的表现方式做保护处理,对上载内容不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知咨信网(发送邮件至1219186828@qq.com、拔打电话4009-655-100或【 微信客服】、【 QQ客服】),核实后会尽快下架及时删除,并可随时和客服了解处理情况,尊重保护知识产权我们共同努力。
温馨提示:如果因为网速或其他原因下载失败请重新下载,重复下载【60天内】不扣币。 服务填表

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

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

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

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

4、int newsize); 语法:指针名=(数据类型*)realloc(要改变内存大小的指针名,新的大小)。//新的大小一定要大于原来的大小,不然的话会导致数据丢失! 头文件:#include 有些编译器需要#include ,在TC2.0中可以使用alloc.h头文件 功能:先判断当前的指针是否有足够的连续空间,如果有,扩大mem_address指向的地址,并且将mem_address返回,如果空间不够,先按照newsize指定的大小分配空间,将原有数据从头到尾拷贝到新分配的内存区域,而后释放原来mem_address所指内存区域(注意:原来指

5、针是自动释放,不需要使用free),同时返回新分配的内存区域的首地址。即重新分配存储器块的地址。 返回值:如果重新分配成功则返回指向被分配内存的指针,否则返回空指针NULL。 由realloc函数定义可知,新分配的内存空间可能是在原有的内存基础上扩充,还有可能是在另外的一个地方新开辟一块内存。无论哪种情况多要对新加的内存进行指针指向分配。并且对于第二种情况,会出现的问题是原有的指针全都失效。因为原有指向的内存已经不存在了,因此指向它的指针将失效,原有分配的对象也将失效。为了解决这个问题,在新分配内存后需要重定向原有的指针,并且使用二级指针改变已经分配了对象的地址的指向,使它指向新内存。

6、 重定向原有内存的指针的指向,和已经分配了内存的对象的指向。 对象释放内存: 假如先前的申请了250个字节分配了三个内存块的用户释放了内存,这时链表指针向后查找直到找到第一个被使用的内存块,或链表结尾。之后在先前查找直到找到前面第一个被使用的内存块或者是头指针,之后更新这个区间段内存块的大小。 释放内存池: 首先释放向系统申请的内存块,之后在清空所有的双向链表。 释放向系统申请的内存 释放双向链表。 后续改进: 1, 需要对多线程的支持,目前的内存池还只能在单线程的环境下运行。 2, 如果之前得到内存的对象,在新内存分

7、配前有指针复制操作,原有对象可以通过保存的指针地址进行重定向,但是之前分别的对象不能保证。引进对于分配的对象尽量不要使用指针复制。如果一定需要这么做,那就在每次使用前,在重定向一下。重新进行一次复制操作(保险起见,不知道我的表述是否清楚明白)。 源代码:   头文件链表节点的定义 #include #include #include #include using namespace std; namespace MemePool { typedef unsigned char

8、EigthByte; //内存池的默认大小和分配节点的默认大小 static const size_t DEFAULTMEMEPOOLSIZE = 1000; static const size_t DEFAULTMEMENODESIZE = 100; //内存初始分配内容 二进制位1111 1111 static const int NEW_ALLOCATED_MEMORY_CONTENT = 0xFF; //内存分配节点(双向链表) typedef struct TMemeNode { //指向前一节点 TMemeNode *first

9、 //指向后一节点 TMemeNode *next; //节点大小 size_t idataSize; //节点是否被使用 bool isUsed; //分配的节点的后一节点 TMemeNode *pEndNode; //记录内存池分配的首地址 bool isMemeBegin; //保存分配的内存地址 EigthByte *Data ; //使用者对象的地址 void **pUser; } TMemeLinkNode; }; 内存池实现: namespace MemePoo

10、l { //内存池的实现 作者邮箱a584851044@ class CMemePool { public: //线程池构造函数 CMemePool(const size_t &sInitialMemoryPoolSize = DEFAULTMEMEPOOLSIZE, const size_t &sMemoryChunkSize = DEFAULTMEMENODESIZE); ~CMemePool(); //分配内存 void *GetMemeroy(void **p,const size_t &sSize);

11、 //释放分配内存 void FreeAllocMemeroy(void *p,const size_t &sSize); //释放内存池所有内存 void FreeAllMemeroy(); //展示内存池的使用情况 void ShowTheMemePoolStatue(); //获取错误信息 void GetErrorInfo(); private: //禁止复制与构造,要传递就用引用吧 CMemePool(CMemePool *tCMemePool); CMeme

12、Pool& operator =(CMemePool &tCMemePool); void AllocPoolMemeroy(); void CalLinkNodeNum(); void CalMemeSize(); void LinkMemeryToNode(EigthByte *PAlloc); void UpdateLinkNodeSize(TMemeNode *PNode); void CalNeetLinkNumber(const size_t &sSize); void* FindMe

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

14、LinkNode *m_LastNode; EigthByte *m_PAlloc; //保存第一次运行头地址 bool m_isFirst; //内存块分配数目 size_t m_Number; //内存块总的数目 size_t m_AllNumber; //每一个内存块的大小 size_t m_MemLinkSize; //内存池分配的大小 size_t m_MemePollSize; //内存块总分配大小 siz

15、e_t m_AllAloctsize; //内存池使用的大小 size_t m_MemePoolUseSize; //内存池空闲的大小 size_t m_MemePoolFreeSize; //分配了多少个对象 size_t m_iUseObject; //保存错误信息 string m_sError; //保存请求分配内存用户信息 void **m_User; }; }; //-------------------------------

16、 //recalloc分配新内存后,之前指向旧内存的指针就失效了 //需要重新定位,之前分配对象的指向也要重新定位 namespace MemePool { /***************************************** 内存池构造函数 by 风清扬song 13-07-28 *****************************************/ CMemePool::CMemePool(const size_t &sInitialMe

17、moryPoolSize,const size_t &sMemoryChunkSize) { //初始化内存池的大小 m_MemePollSize = sInitialMemoryPoolSize; //初始化每个内存块的大小 m_MemLinkSize = sMemoryChunkSize; //初始化一些参数 m_MemePoolFreeSize = 0; m_MemePoolUseSize = 0; m_Current = NULL; m_LastNode = NULL; m_Number = 0; m_AllAloctsize = 0;

18、 m_AllNumber = 0; m_iUseObject = 0; m_Head = new TMemeLinkNode; m_Head->next = NULL; m_Head->first = NULL; m_Head->Data = NULL; m_isFirst = true; //分配线程池函数 AllocPoolMemeroy(); } /***************************************** 内存池析构函数 by 风清扬song 13-07-28 ****************

19、/ CMemePool::~CMemePool() { FreeAllMemeroy(); } /***************************************** 内存池分配内存函数 by 风清扬song 13-07-28 *****************************************/ void CMemePool::AllocPoolMemeroy() { //计算需要的链表节点数目 CalLinkNodeNum(); //计算真正要分配的内存大小

20、 CalMemeSize(); m_AllNumber = m_AllNumber + m_Number; m_AllAloctsize += m_MemePollSize; m_MemePoolFreeSize += m_MemePollSize; //追加分配内存,原有内存的内容不会受到影响 m_PAlloc = (EigthByte *)realloc(m_PAlloc,(m_AllAloctsize)*sizeof(EigthByte)); //内存分配失败 if(NULL == m_PAlloc) { m_sError = "Alloc

21、Memeroy Pool Failture"; return; } //不是第一次分配内存 if(false == m_isFirst) { //新分配内存后原有指针全失效,需要重定向 ResetLinkToMemery(); } //分配的内存内容初始化 // memset(((void *) PAlloc), NEW_ALLOCATED_MEMORY_CONTENT, m_MemePollSize) ; //将分配的线程池内存与链表节点关联 LinkMemeryToNode(&m_PAlloc[m_AllAloctsize - m_Me

22、mePollSize]); } /***************************************** 将原内存的指针进行重定向(Alloc后原有内存可能被释放了) by 风清扬song 13-07-28 *****************************************/ void CMemePool::ResetLinkToMemery() { TMemeLinkNode *pTemp = m_Head->next; int iIndex = 0; while(NULL != pTemp) {

23、 //重定向指针链表的指向 pTemp->Data = &m_PAlloc[iIndex * m_MemLinkSize]; if(NULL != pTemp->pUser) { //重定向用户指针的指向 *pTemp->pUser = pTemp->Data; } iIndex++; pTemp = pTemp->next; } } /***************************************** 计算需要的内存链表节点数目 by 风清

24、扬song 13-07-28 *****************************************/ void CMemePool::CalLinkNodeNum() { float fTempValue = m_MemePollSize / m_MemLinkSize; //向上取整需要的节点数目 m_Number = ceil(fTempValue); } /***************************************** 计算内存池真正分配的内存的大小 by 风清扬song 13-07-28 ****

25、/ void CMemePool::CalMemeSize() { m_MemePollSize = (size_t)(m_Number * m_MemLinkSize); } /***************************************** 将分配的内存和链表节点相关联 by 风清扬song 13-07-28 *****************************************/ void CMemePool::LinkMemeryToNode(E

26、igthByte *PAlloc) { TMemeLinkNode *PNode; //遍历每一个节点分配空间 for(size_t iIndex = 0; iIndex < m_Number ; iIndex ++) { PNode = new TMemeLinkNode(); if(NULL == m_LastNode) { PNode->next = m_Head->next; m_Head->next = PNode; PNode->first = m_Head; m_LastN

27、ode = PNode; } else { PNode->next = m_LastNode->next; m_LastNode->next = PNode; PNode->first = m_LastNode; m_LastNode = PNode; } m_LastNode->isUsed = false; m_LastNode->idataSize = m_MemePollSize - iIndex * m_MemLinkSize; m_LastNode->Data

28、 = &PAlloc[iIndex * m_MemLinkSize]; m_LastNode->isMemeBegin = false; m_LastNode->pUser = NULL; //记录内存块的首地址,释放时使用 if(true == m_isFirst && 0 == iIndex) { m_LastNode->isMemeBegin = true; m_isFirst = false; } } UpdateLinkNodeSize(m_LastNode); } /****

29、 更新当前节点的前后大小值 by 风清扬song 13-07-28 *****************************************/ void CMemePool::UpdateLinkNodeSize(TMemeNode *PNode) { TMemeNode *PTemp; PTemp = PNode->next; int iDateSize = 0; //当前节点的后一个节点没分配,得到它的DataSize值 if(NULL != PTemp && f

30、alse == PTemp->isUsed) { iDateSize = PTemp->idataSize; } //由最后一个节点在向前遍历,更新所有的节点大小值 int iIndex = 1; while(PNode != m_Head && false == PNode->isUsed) { PNode->idataSize = iIndex * m_MemLinkSize + iDateSize; iIndex++; PNode = PNode->first; } m_Current = PNode->next; }

31、 /***************************************** 分配内存空间 by 风清扬song 13-07-28 *****************************************/ void *CMemePool::GetMemeroy(void **p,const size_t &sSize) { m_MemePoolFreeSize -= sSize; m_MemePoolUseSize += sSize; //保存请求内存分配的用户信息 m_User = p; //增加分配对象数目

32、 m_iUseObject++; //有合适的内存块 void *pFind = FindMemeNode(sSize); if(NULL != pFind) { return pFind; } TMemeNode *PTemp; PTemp = m_Current; m_Current = m_Current->next; //遍历内存块找到合适的内存 while(PTemp != m_Current) { //走到结尾,从头来 if(NULL == m_Current) { m_Current = m

33、Head->next; } //跳过已经分配的节点 if(true == m_Current->isUsed) { m_Current = m_Current->pEndNode; // m_Current = m_Current->first; } pFind = FindMemeNode(sSize); if(NULL != pFind) { return pFind; } if(PTemp == m_Current) { break; } m_Current =

34、m_Current->next; } //在当前的所有节点链表中没有合适的,新分配吧 m_MemePollSize = sSize; AllocPoolMemeroy(); return FindMemeNode(sSize); } /***************************************** 计算所需的内存块数目 by 风清扬song 13-07-28 *****************************************/ void CMemePool::CalNeetLinkNumber(c

35、onst size_t &sSize) { float fTempValue = sSize / m_MemLinkSize; //向上取整需要的节点数目 m_Number = ceil(fTempValue); if(0 == m_Number) { m_Number = 1; } } /***************************************** 找到合适的内存分配节点了 by 风清扬song 13-07-28 *****************************************/ v

36、oid* CMemePool::FindMemeNode(const size_t &sSize) { if(m_Current->idataSize >= sSize && false == m_Current->isUsed) { CalNeetLinkNumber(sSize); size_t iIndex = 0; TMemeLinkNode *pTemp = m_Current; while(iIndex < m_Number) { m_Current->isUsed = true; m_Current = m_Curr

37、ent->next; iIndex++; } //保存分配内存的用户信息 pTemp->pUser = m_User; //记录分配了几块内存,避免后续遍历 pTemp->pEndNode = m_Current->next; return pTemp->Data; } else { return NULL; } } /***************************************** 收回分配的内存块 by 风清扬song 13-07-28 *******************

38、/ void CMemePool::FreeAllocMemeroy(void *p,const size_t &sSize) { //减少分配数目 m_iUseObject--; m_MemePoolUseSize -= sSize; m_MemePoolFreeSize += sSize; TMemeNode *pFind = SearchAllocNode(p); if(NULL == pFind) { m_sError = "can not find the alloc point,you

39、may use wrong"; } //恢复内存为初始化 //memset(((void *) pFind->Data), NEW_ALLOCATED_MEMORY_CONTENT, sSize) ; //计算向后移动多少内存块 CalNeetLinkNumber(sSize); size_t iIndex = 0; while(iIndex != m_Number) { pFind->isUsed = false; pFind = pFind->next; iIndex++; } //内存归还后,更新前后节点的

40、大小 UpdateLinkNodeSize(pFind->first); } /***************************************** 查找之前分配内存的节点 by 风清扬song 13-07-28 *****************************************/ TMemeNode * CMemePool::SearchAllocNode(void *p) { TMemeNode *PTemp = m_Head->next; while(NULL != PTemp) { if(P

41、Temp->Data == (EigthByte *) p) { //释放内存的用户清空之前保存的用户信息 PTemp->pUser = NULL; return PTemp; } PTemp = PTemp->next; } return NULL; } /***************************************** 清空线程池 by 风清扬song 13-07-28 *****************************************/ void CMemePool:

42、FreeAllMemeroy() { //所有内存对象都释放了 if(0 != m_iUseObject) { m_sError = "warning there is some object not release"; } CleanAllMemeDate(); CleatAllLinkNode(); } /***************************************** 清空向系统申请的内存 by 风清扬song 13-07-28 ****************************************

43、/ void CMemePool::CleanAllMemeDate() { TMemeLinkNode *pTemp = m_Head->next; while(NULL != pTemp) { //内存被连城了一块,从首地址就可以全部删除 if(pTemp->isMemeBegin&&NULL != pTemp->Data) { delete []pTemp->Data; return; } pTemp = pTemp->next; } } /**************************

44、 清空双向链表 by 风清扬song 13-07-28 *****************************************/ void CMemePool::CleatAllLinkNode() { TMemeLinkNode *pTemp = m_Head->next; while(NULL != pTemp) { TMemeLinkNode *qTemp = pTemp; pTemp = pTemp->next; delete qTemp; }

45、if(NULL != m_Head) { delete m_Head; } } /***************************************** 显示内存池运行状态 by 风清扬song 13-07-28 *****************************************/ void CMemePool::ShowTheMemePoolStatue() { cout<<"\n\n\t\t\t内存池使用状况输出\t\t\t\n\n"; cout<<"\t\t总内存池大小:"<

46、octsize<<"使用大小:"<next; int iIndex = 1; while(NULL != pTemp) { cout<<"\n内存池号:"<idataSize<<"\t\t是否被使用:"<isUsed<next; } }

47、}; 测试代码: int main(int argc, char* argv[]) { CMemePool *g_ptrMemPool = new CMemePool() ; char *ptrCharArray = (char *) g_ptrMemPool->GetMemeroy((void**)&ptrCharArray,700) ; g_ptrMemPool->ShowTheMemePoolStatue(); char * ptrCharArrayB = (char *) g_ptrMemPool->GetMemeroy((void**)&p

48、trCharArrayB,80) ; g_ptrMemPool->ShowTheMemePoolStatue(); char * ptrCharArrayC = (char *) g_ptrMemPool->GetMemeroy((void**)&ptrCharArrayC,400) ; g_ptrMemPool->ShowTheMemePoolStatue(); g_ptrMemPool->FreeAllocMemeroy(ptrCharArray, 700) ; g_ptrMemPool->ShowTheMemePoolStatue(); g

49、ptrMemPool->FreeAllocMemeroy(ptrCharArrayC, 400) ; g_ptrMemPool->FreeAllocMemeroy(ptrCharArrayB, 80) ; ptrCharArray = (char *) g_ptrMemPool->GetMemeroy((void**)&ptrCharArray,1300) ; g_ptrMemPool->ShowTheMemePoolStatue(); for(int i=0; i< 1200; i++) { ptrCharArray[i] = 'a'; } g_ptrMemPool->ShowTheMemePoolStatue(); char c = ptrCharArray[800]; g_ptrMemPool->FreeAllocMemeroy(ptrCharArray, 1300) ; g_ptrMemPool->ShowTheMemePoolStatue(); delete g_ptrMemPool ; std::cout << "MemoryPool Program finished..." << std::endl ; system("PA

移动网页_全站_页脚广告1

关于我们      便捷服务       自信AI       AI导航        抽奖活动

©2010-2026 宁波自信网络信息技术有限公司  版权所有

客服电话:0574-28810668  投诉电话:18658249818

gongan.png浙公网安备33021202000488号   

icp.png浙ICP备2021020529号-1  |  浙B2-20240490  

关注我们 :微信公众号    抖音    微博    LOFTER 

客服