关于CStringList的剖析

CStringList是一个双向链表。它的内存管理依赖于CPlex结构。

__declspec(align(8)) struct CPlex
{
	CPlex* pNext;
	// BYTE data[maxNum*elementSize];

	void* data() { return this+1; }

	static CPlex* PASCAL Create(CPlex*& head, UINT_PTR nMax, UINT_PTR cbElement);
			// like 'calloc' but no zero fill
			// may throw memory exceptions
	void FreeDataChain();       // free this one and links
}; 

CPlex是一块内存块,除去保存下一个内存块的pNext这个指针所占用的内存,它最多能容纳m个sizeof(CNode)的空间。m由CStringList的构造函数传入,默认为10。m_pBlocks指向第一个内存块,之后的内存块都已有元素。

class CStringList
{
  CNode* m_pNodeHead; //头节点,指向第一个元素
  CNode* m_pNodeTail;//尾节点,指向最后一个元素
  INT_PTR m_nCount; //元素个数,节点个数
  CNode* m_pNodeFree;//第一个空闲节点(节点被分配空间,但没有赋值)
  struct CPlex* m_pBlocks;//第一个内存块
  INT_PTR m_nBlockSize;//每个内存块最多能存储节点的个数,每个内存块能存储m_nBlockSize*sizeof(CNode)+sizeof(CPlex)
};


CStringList利用m_pNodeFree实现了一个简单的内存池,需要销毁一个元素的时候,并不真正的销毁,而是将它放到内存池中。需要申请元素的时候,直接往内存池中申请。只有当m_nBlockSize为0或者调用RemoveAll时,才真正的释放所有所申请的内存。

posted @ 2024-06-20 17:30  DJFFding  阅读(72)  评论(0)    收藏  举报