CMapPtrtoPtr的数据项由3部分组成,指向下一个数据项的指针,两个相关联的指针。定义如下:
struct CAssoc
{
CAssoc* pNext;
void* key;
void* value;
};
这里相关联的含义是单向关联,即给某个value指针关联了一个key指针,我们可以通过key指针查找或删除对应value指针。现在我们思考一下CMapPtrtoPtr应该支持的基本操作,很明显的是我们应该提供添加一个关联项,查找某个key对应的value,删除key对应的关联项,删除所有数据项。
首先我们来考虑添加一个关联项,根据前面的数据项定义,我们很容易想到可以申请一块数据项内存初始化我们的数据并以链表的形式串联起来。这样想来是比较容易,但如果我们的数据量比较大,我们就有可能大量的进行分配内存的操作,与之对应的当然还有释放内存的操作,这些操作的开销是会非常大的,而且我们分配的内存是不连续的空间,那么当分配的内存之间的大小不足以分配数据项时就会出现内存碎片。为了解决这个问题,我们希望能够分配一整块连续的内存,当为CAssoc分配空间的时候使用我们事先分配好的空间,直到该空间使用完再申请, 当然这一整块空间的大小,可以由用户根据自己的需要指定。为此我们引入了一个辅助的管理内存的数据结构:CPlex,定义如下:
StructCPlex
{
CPlex* pNext;
void* data() {return this+1;}
static CPlex* Create(CPlex* pHead, UINT nMax, UINT cbElement);
void FreeDataChain();
}
其中静态函数Create实现了分配nMax个大小为cbElement的连续空间,并将该空间添加到以pHead为链表头的链表中。
CPlex* 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 FreeDataChain()
{
CPlex * p = this;
while(p != NULL)