框架管理基础之内存映射

来源:互联网 发布:淘宝客软件下载 编辑:程序博客网 时间:2024/05/16 17:50

一. 映射的概念:定义域中x的任一取值,都有惟一的y值与之对应。

在处理窗口消息的时候,要通过钞口王居士WndProc传来的窗口句柄的值得到此窗口对应的CWnd指针,然后用这个指针去调用CWnd类的接口成员。

二.内存的分配方式:

1.      指针到指针的影射结构:struct CAssoc{ CAssoc * pNext; vid *key; void * value;};

2.      如果要用成千上万个CAssoc结构,那么每个单独new,和delete的开销太大,没还容易造成内存碎片。

解决方案:预先为CAssoc结构预先申请一块较大的内存,要为CAssoc分配空间的时候,并不真的申请新的空间,而是使用上面预留的空间。

 (静态成员是类的所有对象共享的成员,不属于任何一个对象,只属于这个类除了静态常量,初始化只能在类外进行,而不能用对象实例化初始k的值,但是静态变量不占用类的空间);包括静态函数成员;

struct CPlex{//在每块内存头部增加的数据可以用CPlex结构表示;

    CPlex*pNext;

    void* data(){returnthis+1;}

    static CPlex* Create(CPlex*& pHead,UINT nMax,UINTcbElement);

    void FreeDataChain();

};

 

CPlex* CPlex::Create(CPlex *&pHead,UINT nMax, UINT cbElement)

{

    CPlex*p = (CPlex*)new BYTE[sizeof(CPlex)+nMax*cbElement];

    p->pNext= NULL;

    p->pNext= pHead;

    pHead= p;

    return pHead;

}

 

voidCPlex::FreeDataChain(){

    CPlex*p = this;//内存块分配空间的释放

    while(p!=NULL)

    {

       BYTE*pb = (BYTE*)p;

       p= p->pNext;

       delete []pb;

    }

}

 

 

实际应用:

CMyData* pData = (CMyData*)pHead->data();

pData++;//向后遍历

三.设计管理方式:

1)  为映射项分配内存空间:

classCMapPtrToPtr{

protected:

    struct CAssoc{

       CAssoc*pNext;

       void *key;

       void *value;

    };

protected:

    //实现;

 

    struct CPlex* m_pBlocks;//CPlex::Create函数申请的内存卡的首地址

    int m_nBlockSize;//指定内存块可以容纳的CAssoc结构数;

    CAssoc*m_pFreeList;//预留空间中第一个没有被使用的CAssoc结构组成的链中第一个关联指针

    int m_nCount;//记录了程序一共使用了多少个CAssoc结构,即关联的个数;

    CAssoc*NewAssoc();//为一个新的CAssoc分配空间

    void FreeAssoc(CAssoc* pAssoc);//释放一个CAssoc结构占用的空间。

 

};

 

CMapPtrToPtr::CAssoc*CMapPtrToPtr::NewAssoc(){

    if(m_pFreeList==NULL){

       CPlex*pcp = CPlex::Create(m_pBlocks,m_nBlockSize,sizeof(CAssoc));

       CAssoc*pAssoc = (CAssoc*)pcp->data();

       pAssoc+=m_nBlockSize-1;

      

       for(int i=0;i<m_nBlockSize;i++)

       {

           pAssoc->pNext= m_pFreeList;

           m_pFreeList= pAssoc;

           pAssoc--;

       }

 

       CAssoc*pAssoc = m_pFreeList;

       m_pFreeList= m_pFreeList->pNext;

       m_nCount++;

       pAssoc->key= 0;

       pAssoc->value= 0;

       return pAssoc;

    }

}

 

 

voidCMapPtrToPtr::FreeAssoc(CMapPtrToPtr::CAssoc *pAssoc){

    pAssoc->pNext= m_pFreeList;

    m_pFreeList= pAssoc;

    m_nCount--;

    if(m_nCount == 0)//此函数会释放所有的内存空间,

       RemoveAll();

}

2)  映射项的内存组织:

1.      为各映射项分配内存空间的方法讲完了,下面要关心的是如何设计各映射项的内存组织形式。

2.      如何实现key-value的快速查找呢?利用哈希表;申请一个CAssoc类型的数组;

M_pHashTable = new CAssoc* [nHashSize];

nHash = hHashValue% m_nHashTableSize;

3.      计算哈希值的原则是尽量使计算出来的值惟一,并且不太大。设计一个成员函数来完成此任务:

 

4.      2

3)  2

原创粉丝点击