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

nbsp; try{ // 分配内存64m_nallocsize.
     pnewblock = cplex::create(m_pblocks, m_nblocksize, m_nallocsize);
       }catch_all(e){
            ...
异常

       }end_catch_all
       //
下面的代是将内存块压m_pnodefree表中待用。
       cnode* pnode = (cnode*)pnewblock->data();
       (byte*&)pnode += (m_nallocsize * m_nblocksize) - m_nallocsize;
       for (int i = m_nblocksize-1; i >= 0; i--, (byte*&)pnode -= m_nallocsize)
       {
    pnode->pnext = m_pnodefree;
    m_pnodefree = pnode;
       }
    }
    //
两句是出一内存给调用者使用。
    void* pnode = m_pnodefree;
    m_pnodefree = m_pnodefree->pnext;
    ...
    return pnode;
}
/*
 
用者free,只是将这块内存重新m_pnodefree表中
 
并非放,而是可用以待后用。
*/
void cfixedalloc::free(void* p)
{
    if (p != null)
    {
        entercriticalsection(&m_protect);
        cnode* pnode = (cnode*)p;
        pnode->pnext = m_pnodefree;
        m_pnodefree = pnode;
        leavecriticalsection(&m_protect);
    }
}
void cfixedalloc::freeall()
{
    entercriticalsection(&m_protect);
    m_pblocks->freedatachain();
    m_pblocks = null;
    m_pnodefree = null;
    leavecriticalsection(&m_protect);
}
/*
  
在析构函数中 freeall放内存
*/
cfixedalloc::~cfixedalloc()
{
    freeall();
   deletecriticalsection(&m_protect);
}


/*
   mfc/include/afxplex_.h
*/
struct cplex     // warning variable length structure
{
    cplex* pnext;
    void* data() { return this+1; }
    static cplex* pascal create(cplex*& head, uint nmax, uint cbelement);
    void freedatachain();       // free this one and links
};
/*
   mfc/src/plex.cpp
*/
cplex* pascal cplex::create(cplex*& phead, uint nmax, uint cbelement)
{
    cplex* p = (cplex*) new byte[sizeof(cplex) + nmax * cbelement];
    p->pnext = phead;
    phead = p;  //
加入

    return p;
}
void cplex::freedatachain()     // free this one and links
{
   cplex* p = this;
   while (p != null){
      byte* bytes = (byte*) p;
      cplex* pnext = p->pnext;
      delete[] bytes;
      p = pnext;
   }
}
============================================================================
在我用一个例来看一下在release版本下的实际内存
以分配10000个 含有"abcdefghijklmnopqrstuvwxyz"串的cstring
   
   
cstring  * strarray[10000];
   
   
for( int =0;i < 10000; i++ )
     strarray[i] = new cstring("abcdefghijklmnopqrstuvwxyz");
字符串小于64所以用了_afxalloc64::alloc;
   
   
----------------------------------------------------------------
_afxalloc64
strcore.cpp中被定如下
:
afx_static cfixedalloc _afxalloc64(round4(65*sizeof(tchar)+sizeof(cstringdata)));
ansi版本下 sizeof(tchar) = 1
sizeof( cstrgindata ) = 12;
65*sizeof(tchar)+sizeof(cstringdata) = 77;
round4用下,将之4的倍数,
#define round(x,y) (((x)+(y-1))&~(y-1))
#define round4(x) round(x, 4)
所以
_afxalloc64(round4(65*sizeof(tchar)+sizeof(cstringdata)))
实际
宏展终为
extern cfixedalloc _afxalloc64( 80,64);
----------------------------------------------------------------
cplex中分配池的大小
sizeof(cplex) + nmax * cbelement = 4+80*64 = 5124 byte.
10000不是64的整数倍 = 要分配157个池
实际分配内存 = 157*5124 = 804468 byte = 804kb.
cstring
for( int =0;i < 10000; i++ )
     delete strarray[i];
cstring _afxalloc64.free.
   
   
cfixedalloc::free实现可知此并没有真正放内存,只是将这该块重新加入m_pnodefree表中待用.
   
   
cfixedalloc放内存操作是在析构函数用,而_afxalloc64是被定义为全局.它的析构函数要到程序退出才能被.
   
   
所以cfixedall
    
    

 

 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值