MFC的CString(VC6) 内存管理分析[1]

cstring 是我们经常用到的,所以有必要它的内存管理模式分析一下.

cstring 内存管理的演变过程如下:

   vc5  单纯的使用new delete方法。
       
字符串操作需要整内存大小.而采用c++操作符 new delete
       
是没有与realloc
功能的。果就是一次的改内存大小都需要
       
增加一次拷
操作。
       
new delete
实现中在程堆中分配。繁地在堆上行小内存分配与
       
必然在堆上
生大量碎片。堆碎片多直接影响了程序效率。
       
于是mfcvc6版本
行了改
          
   vc6 
于大于512的内存和debug模式下,cstring仍然使用 new delete来操
       
release模式下不大于512
的内存分配操作采用了内存池管理。
       
并将之
<=64, <=128, <=256, <=512 4个内存池管理。
 
这样在不大于512的情况下cstring有了很好的效率。
       
但是
传说中有解决一个bug就会生另外一个bug的定律。
 cstring
然也无法避免它。
       
       
于是在vc7中又改了。
 
   vc7
使用c 的内存管理用方式。即采用 alloc, free, realloc. cstring存在的问题
      
就是由于newdelete没有realloc重新整内存大小的功能。之前生的问题导致最
      
是采用了c的管理方法。

vc6了解决cstring小内存操的性能问题 mfcrelease版本下于不大于512的内存分配
采用的内存池管理来
化。其他情况下仍旧使用new delete.

release版本下cstring理不大于512byte字串的内存时调用如下
vc6
cstring 分配内存与
放内存用次序如下

cstring::allocbuffer
         cfixedalloc::alloc
                    cplex::create

cstring::freedata
         cfixedalloc::free
=========================================================================================
引用如下:
file:mfc/src/strcore.cpp
void cstring::allocbuffer(int nlen) //
用来分配内存
{
    ...
 #ifndef _debug   //
release 版本并且是不大于512

 if (nlen <= 64)
        {
     pdata = (cstringdata*)_afxalloc64.alloc();
            pdata->nalloclength = 64;
 }
 else
别为<= 1128, <=256 , <=512
 {
            ...
 }
 else
#endif           // debug
release下大于512
 {
     pdata = (cstringdata*)
     new byte[sizeof(cstringdata) + (nlen+1)*sizeof(tchar)];
     pdata->nalloclength = nlen;
 }
   ...
}

void fastcall cstring::freedata(cstringdata* pdata) // 放内存
{
#ifndef _debug 
release 版本并且是不大于512

 int nlen = pdata->nalloclength;
 if (nlen == 64)  //
根据内存大小分别调用管理器
    _afxalloc64.free(pdata);
 else if (nlen == 128)
    _afxalloc128.free(pdata);
 else if (nlen == 256)
    _afxalloc256.free(pdata);
 else  if (nlen == 512)
    _afxalloc512.free(pdata);
 else
 {
  assert(nlen > 512);
  delete[] (byte*)pdata;
 }
#else  // debug
release下大于512
 delete[] (byte*)pdata;
#endif
}

_afxalloc[64,128,256,512] cfixedalloc的全局象。

分析一下cfixedalloc是整样进行内存池管理的它在使用中又生了什么问题


class cfixedalloc  //
mfc/src/fixalloc.h文件中
{
public:
 cfixedalloc(uint nallocsize, uint nblocksize = 64);
 uint getallocsize() { return m_nallocsize; }
public:
 void* alloc();  //
分配 由cstring

 void free(void* p); //
放 由cstring
 void freeall(); //
放所有 被析构函数
public:
 ~cfixedalloc();
protected:
 struct cnode{//
个是用来实现一个
     cnode* pnext;  
 };
 uint m_nallocsize;  //
需要分配
象的大小由构造函数
 uint m_nblocksize;  //
分配的数目即池的大小,由构造函数予,可知默认为64
 cplex* m_pblocks;   //
池的表指cplex象含有一个cplex* pnext针对象,
 cnode* m_pnodefree; //
块链表的,实际看做可用内存块链
 critical_section m_protect;//
界区
};

/*
 
alloc实现中我可以看到,当池中没有可用
 
cplex::create建立一 m_nallocsize * m_nblocksize的内存池
 
如果有的
话则m_pnodefree出一来使用
*/
void* cfixedalloc::alloc()
{
    if (m_pnodefree == null){ //
如果没有可用的内存
行分配一个池
       cplex* pnewblock = null;
     &

 
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值