当前位置:七道奇文章资讯编程技术VC/C++编程
日期:2011-03-22 13:56:00  来源:本站整理

<b>为C++尺度库容器写自己的内存分配程序</b>[VC/C++编程]

赞助商链接



  本文“<b>为C++尺度库容器写自己的内存分配程序</b>[VC/C++编程]”是由七道奇为您精心收集,来源于网络转载,文章版权归文章作者所有,本站不对其观点以及内容做任何评价,请读者自行判断,以下是其具体内容:

按照sgi 的STL源码的二级分配算法改写的内存池分配程序,只要略微改正便可以实现同享内存方法管理,利用C++尺度库容器中的map,set,multimap,multiset测试通过,vector测试通不过,缘由是在内存回收的时刻考虑的对比简单,vector每次分配内存个数不固定,回收也不固定,这样的话,程序还需求持续完善.

内存池管理程序源码以下:

以下是引用片段:
#ifndefMY_ALLOCATOR_H_
#defineMY_ALLOCATOR_H_
#include"stdafx.h"
#include<limits>
#include<iostream>
namespacehappyever 
{
  enum{NODENUMS=2};
  union_Obj 
  {
   union_Obj*M_free_list_link;
   charM_client_data[1];  
  };
  typedefunion_ObjObj;
  struct_Cookie
  {
   intiShmKey;    /*同享内存键值*/
   intiShmID;    /*iShmKey对应的shmid*/
   intiSemKey;    /*锁信号键值*/
   intiSemID;    /*锁信号标识*/
   intiTotalsize;  /*容器总容量*/
   void*pStartall; /*同享内存自身地址*/
   char*pStartfree; /*安闲空间的开始地址*/
   char*pEndfree;  /*安闲空间的完毕地址*/
   intiUseNum[NODENUMS];
   /*用来存放free_list中节点的size*/
   shortsFreelistIndex[NODENUMS];
   /*存放分配内存节点的链表*/
   Obj*uFreelist[NODENUMS];
  };
  typedefstruct_CookieCookie;
  //Obj;
  //Cookie;
  staticCookie*pHead=NULL;
  template<classT>
  classMyAlloc 
  {
  private:
   staticconstintALIGN=sizeof(Obj);
   intround_up(intbytes);
   intfreelist_index(intbytes);
   intfreelist_getindex(intbytes);
   char*chunk_alloc(intsize,int*nobjs);
   void*refill(intnum,intn);
  public:
   //typedefinitions
   typedefT    value_type;
   typedefT*   pointer;
   typedefconstT*const_pointer;
   typedefT&   reference;
   typedefconstT&const_reference;
   typedefstd::size_t  size_type;
   typedefstd::ptrdiff_tdifference_type;
   template<classU>
   structrebind 
   {
    typedefMyAlloc<U>other;
   };
   pointeraddress(referencevalue)const 
   {
    return&value;
   }
   const_pointeraddress(const_referencevalue)const 
   {
    return&value;
   }
   MyAlloc()throw() 
   {
    std::cout<<"MyAlloc"<<std::endl;
   }
   MyAlloc(constMyAlloc&x)throw() 
   {
    std::cout<<"constMyAlloc"<<std::endl;
   }
   template<classU>
   MyAlloc(constMyAlloc<U>&x)throw()
   {
    std::cout<<"constMyAlloc<U>"<<std::endl;
   }
   ~MyAlloc()throw() 
   {
    std::cout<<"~MyAlloc"<<std::endl;
   }
   size_typemax_size()constthrow() 
   {
    returnstd::numeric_limits<std::size_t>::max()/sizeof(T);
   }
   //voidPrintFreelistAndCookie();
   pointerallocate(size_typenum,constvoid*=0) 
   {
    pointerret=0;
    Obj**my_free_list;
    Obj*result;
    intindex;
    //printmessageandallocatememorywithglobalnew
    std::cerr<<"allocate"<<num<<"element(s)"
     <<"ofsize"<<sizeof(T)<<std::endl;
    index=freelist_index(sizeof(T));
    if(index>=NODENUMS)
    {
     returnNULL;
    }
    my_free_list=pHead->uFreelist+index;
    //Lock(semid,LOCK_NUM);
    result=*my_free_list;
    if(result==0)
    {
     ret=(pointer)refill((int)num,round_up(sizeof(T)));
    }
    else
    {
     *my_free_list=result->M_free_list_link;
     ret=(pointer)result;
    }
    //UnLock(semid,LOCK_NUM);
    pHead->iUseNum[index]=pHead->iUseNum[index]+(int)num;
    if(0==ret)
    {
     std::cerr<<"allocmemoryfail!"<<std::endl;
     exit(1);
    }
    std::cerr<<"allocatedat:"<<(void*)ret<<std::endl;
    PrintFreelistAndCookie();
    returnret;
   }
   voidconstruct(pointerp,constT&value) 
   {
    //initializememorywithplacementnew
    new((void*)p)T(value);
   }
   voiddestroy(pointerp) 
   {
    //destroyobjectsbycallingtheirdestructor
    p->~T();
   }
   voiddeallocate(pointerp,size_typenum) 
   {
    Obj**my_free_list;
    Obj*q;
    intindex;
    index=freelist_getindex(sizeof(T));
    if(index>=NODENUMS)
    {
     std::cerr<<"deallocatememoryfail!"<<std::endl;
     exit(1);
    }
    my_free_list=pHead->uFreelist+index;
    q=(Obj*)p;
    //Lock(semid,LOCK_NUM);
    /*这个地方大概会有问题*/
    //for(inti=0;i<(int)num;i++)
    {
     q->M_free_list_link=*my_free_list;
     *my_free_list=q;
    }
    //UnLock(semid,LOCK_NUM);
    pHead->iUseNum[index]=pHead->iUseNum[index]-(int)num;
   
    std::cerr<<"deallocate"<<num<<"element(s)"
     <<"ofsize"<<sizeof(T)
     <<"at:"<<(void*)p<<std::endl;
    PrintFreelistAndCookie();
   }
  };
  template<classT>
  intMyAlloc<T>::round_up(intbytes)
  {
   inti;
   i=bytes;
   if(bytes<ALIGN)
   {
    i=ALIGN;
   }
   std::cout<<"round_up:bytes="<<bytes<<",return="<<i<<std::endl;
   returni;
  };
  template<classT>
  intMyAlloc<T>::freelist_index(intbytes)
  {
   inti;
   for(i=0;i<NODENUMS;i++)
   {
    if(pHead->sFreelistIndex[i]==bytes)
     break;
   }
   if(i>=NODENUMS)
   {
    for(i=0;i<NODENUMS;i++)
    {
     if(pHead->sFreelistIndex[i]==0)
     {
      pHead->sFreelistIndex[i]=bytes;
      std::cout<<"freelist_index:bytes="<<bytes<<",return="<<i<<std::endl;
      returni;
     }
    }
   }
   std::cout<<"freelist_index:bytes="<<bytes<<",return="<<i<<std::endl;
   returni;
  };
  template<classT>
  intMyAlloc<T>::freelist_getindex(intbytes)
  {
   inti;
   for(i=0;i<NODENUMS;i++)
   {
    if(pHead->sFreelistIndex[i]==bytes)
     break;
   }
   std::cout<<"freelist_getindex:bytes="<<bytes<<",return="<<i<<std::endl;
   returni;
  };
  template<classT>
  char*MyAlloc<T>::chunk_alloc(intsize,int*nobjs)
  {
   char*result;
   intcounts=*nobjs;
   inttotal_bytes=size*counts;
   intbytes_left=int(pHead->pEndfree-pHead->pStartfree);
   std::cout<<"chunk_alloc:total_bytes="<<total_bytes
    <<",bytes_left="<<bytes_left<<std::endl;
   if(bytes_left>=total_bytes)
   {
    result=pHead->pStartfree;
    pHead->pStartfree+=total_bytes;
    std::cout<<"chunk_alloc:total_bytes="<<total_bytes
     <<",result="<<*result<<",start_free="<<&(pHead->pStartfree)<<std::endl;
   }
   elseif(bytes_left>=size)
   {
    counts=bytes_left/size;
    total_bytes=size*counts;
    result=pHead->pStartfree;
    pHead->pStartfree+=total_bytes;
    *nobjs=counts;
    std::cout<<"chunk_alloc:total_bytes="<<total_bytes<<",nobjs="<<nobjs
     <<",result="<<*result<<",start_free="<<&(pHead->pStartfree)<<std::endl;
   }
   else
   {
    /*还需求处理回收其他闲暇freelist里面的空间*/
    result=NULL;
   }
   return(result);
  };
  template<classT>
  void*MyAlloc<T>::refill(intnum,intn)
  {
   intcounts=num;
   int*nobjs=&counts;
   char*chunk;
   Obj**my_free_list;
   Obj*result;
   Obj*current_obj;
   Obj*next_obj;
   inti;
   chunk=chunk_alloc(n,nobjs);
   if(chunk==NULL)
   {
    return(chunk);
   }
   counts=*nobjs;
   if(1==counts)
   {
    return(chunk);
   }
   my_free_list=pHead->uFreelist+freelist_index(n);
   result=(Obj*)chunk;
   *my_free_list=next_obj=(Obj*)(chunk+n*num);
   for(i=1;;i++)
   {
    current_obj=next_obj;
    next_obj=(Obj*)((char*)next_obj+n);
    if(counts-1==i)
    {
     current_obj->M_free_list_link=0;
     break;
    }
    else
    {
     current_obj->M_free_list_link=next_obj;
    }
   }
   return(result);
  };
/*这个函数可以改写成自己的同享内存分配函数*/ 
staticvoidInitShm()
  {
   inti,size=1000;
   pHead=(Cookie*)malloc(sizeof(Cookie)+size);
   pHead->iTotalsize=sizeof(Cookie)+size;
   pHead->pStartall =pHead;
   pHead->pStartfree=(char*)pHead+sizeof(Cookie);
   pHead->pEndfree =(char*)pHead+pHead->iTotalsize;
   for(i=0;i<NODENUMS;i++)
   {
    pHead->sFreelistIndex[i]=0;
    pHead->uFreelist[i]=0;
    pHead->iUseNum[i]=0;
   }
  }
  staticvoidPrintFreelistAndCookie()
  {
   inti,j;
   Obj*my_free_list;
   std::cout<<"Cookieinfo:"<<std::endl;
   std::cout<<"sizeof(structCookie)="<<sizeof(Cookie)<<std::endl;
   std::cout<<"Totalsize  ="<<pHead->iTotalsize<<std::endl;
   std::cout<<"UsedSize   ="<<int(pHead->pStartfree-(char*)pHead)<<std::endl;
   std::cout<<"FreepoolSize ="<<int(pHead->pEndfree-pHead->pStartfree)<<std::endl;
   std::cout<<"Startall   ="<<&(pHead->pStartall)<<std::endl;
   std::cout<<"Startfree  ="<<&(pHead->pStartfree)<<std::endl;
   std::cout<<"Endfree   ="<<&(pHead->pEndfree)<<std::endl;
   std::cout<<"nFreelistinfo:"<<std::endl;
   for(i=0;i<NODENUMS;i++)
   {
    j=0;
    std::cout<<"iUseNum["<<i<<"]="<<pHead->iUseNum[i]<<std::endl;
    std::cout<<"FreelistIndex["<<i<<"]="<<pHead->sFreelistIndex[i]<<std::endl;
    my_free_list=pHead->uFreelist[i];
    if(my_free_list->M_client_data!=0)
    {
     while(my_free_list->M_client_data!=0)
     {
      j++;
      my_free_list=my_free_list->M_free_list_link;
     }
     std::cout<<"free_list["<<i<<"];nodecounts="<<j<<std::endl;
    }
   }
  }
  template<classT1,classT2>
  booloperator==(constMyAlloc<T1>&,constMyAlloc<T2>&)throw() 
  {
   returntrue;
  }
  template<classT1,classT2>
  booloperator!=(constMyAlloc<T1>&,constMyAlloc<T2>&)throw() 
  {
   returnfalse;
  }
}
#endif/*MY_ALLOCATOR_H_*/
测试程序的源码以下:
//MyStl.cpp:定义掌握台利用程序的进口点.
//
#include"stdafx.h"
#include<map>
#include<vector>
#include<string>
#include<utility>
#include<iostream>
#include"MyAlloc.h"
usingnamespacestd;
int_tmain(intargc,_TCHAR*argv[])
{
  happyever::InitShm();
  multimap<string,int,less<string>,happyever::MyAlloc<string>>m;
  m.insert(make_pair(string("Harry"),32));
  m.insert(make_pair(string("Mary"),59));
  m.insert(make_pair(string("Roger"),18));
  m.insert(make_pair(string("Nancy"),37));
  m.insert(make_pair(string("Mary"),23));
 
  typedefmultimap<string,int,less<string>,happyever::MyAlloc<string>>::iteratorIter;
  for(Iterp=m.begin();p!=m.end();p++)
  {
   cout<<p->first<<","<<p->second<<endl;
  }
  Iterp=m.find("Harry");
  m.erase(p);
  /*p=m.find("Harry");
  cout<<"Harryis:"<<p->second<<"."<<endl;*/
  for(Iterp=m.begin();p!=m.end();p++)
  {
   cout<<p->first<<","<<p->second<<endl;
  }
 
  return0;
}
以上程序在vs2005,vc6上测试通过.利用MinGW编译的时刻只需求去掉vc的预编译头文件#include"stdafx.h"
便可.

以上程序只要略微改正,便可以实现同享内存的管理,可以便利的利用尺度库供应的容器.加上信号量的锁机制.

以上为了学习而改写的SGI的stl二级分配算法实现的.以上代码存在一定的范围性.我别的完好实现了同享内存管理的STL尺度的alloctor程序,利用posix信号量加锁.目前利用在aix的xlC编译环境下.因为源码触及公司的商业奥秘,所以不能公开.但基本上以上源码已经表现了自己管理内存的完好思绪,供这方面需求的朋友一同学习研究用.


  以上是“<b>为C++尺度库容器写自己的内存分配程序</b>[VC/C++编程]”的内容,如果你对以上该文章内容感兴趣,你可以看看七道奇为您推荐以下文章:
  • <b>hosts是什么 hosts文件在什么位置 若何改正hosts</b>
  • <b>在 Windows 8 中手动安装语言包</b>
  • <b>五个常见 PHP数据库问题</b>
  • Windows中Alt键的12个高效快速的利用本领介绍
  • <b>MySQL ORDER BY 的实现解析</b>
  • <b>详解MySQL存储历程参数有三种范例(in、out、inout)</b>
  • <b>Win8系统恢复出来经典的开始菜单的办法</b>
  • <b>Win8系统花屏怎么办 Win8系统花屏的办理办法</b>
  • <b>Windows 7系统下无线网卡安装</b>
  • <b>为什么 Linux不需求碎片整理</b>
  • <b>Windows 8中删除账户的几种办法(图)</b>
  • <b>教你如安在win7下配置路由器</b>
  • 本文地址: 与您的QQ/BBS好友分享!
    • 好的评价 如果您觉得此文章好,就请您
        0%(0)
    • 差的评价 如果您觉得此文章差,就请您
        0%(0)

    文章评论评论内容只代表网友观点,与本站立场无关!

       评论摘要(共 0 条,得分 0 分,平均 0 分) 查看完整评论
    Copyright © 2020-2022 www.xiamiku.com. All Rights Reserved .