编程语言

img yellowdawnhlm

任意大小分配的内存池实现

发表于2004/10/11 15:13:00  1251人阅读

最近在写多媒体流方面的东西,发现要频繁的分配内存,如果采用new来分配速度会很慢,于是自己做了一个内存池。但是如果要开发任意大小分配的内存池是非常困难的,而且不能保证有new的速度快,在网上看到的内存池一般都是固定大小分配的。虽然任意大小分配的内存池很难实现,但是在某些特殊条件下,就变的很容易了。比如:如果内存释放的顺序是按分配的顺序释放的,这种情况在使用队列来存储大量数据的情况下非常有用。

 

实现这种内存池只需要一段较大的缓冲区和两个指针,一个标示已分配空间头的位置,一个表示已分配空间尾部位置。如果内存池没有足够的空间就退化为使用new来分配。

 

分配实现:

/*

 *  @func:  Alloc

 *  @brief: 分配nSize大小的空间

 *  @param: [in]  ULONG nSize 要分配的空间大小

 *  @ret:   PVOID     分配的空间的起始地址

 */

 

PVOID CRandomMemPool::Alloc(ULONG nSize)

{

       CAutoLock lock(&m_Lock);

 

       PBYTE pPtr = NULL;

       if (m_nTail > m_nHeader || (m_nTail == m_nHeader && m_nPoolLeft > 0))

       {

              if (m_nPoolSize - m_nTail >= nSize)

              {

                     pPtr = m_pPool + m_nTail;

                     m_nTail += nSize;

              }else if (m_nHeader >= nSize)

              {

                     pPtr = m_pPool;

                     m_nTail = nSize;

              }

       }else if (m_nTail < m_nHeader)

       {

              if (m_nHeader - m_nTail >= nSize)

              {

                     pPtr = m_pPool + m_nTail;

                     m_nTail += nSize;

              }

       }

 

       if (pPtr == NULL)

       {

              TRACE("the memory pool is empty, use new to alloc/r/n");

              pPtr = new BYTE[nSize];

       }else

       {

              m_nPoolLeft -= nSize;

       }

      

       return pPtr;

}

 

释放实现:

/*

 *  @func:  Free

 *  @brief: 释放空间,必须指定内存空间大小

 *  @param: [in]  PVOID pPtr    内存空间

 *                  [in]  ULONG uSize 内存空间大小

 *  @ret:   void

 */

void CRandomMemPool::Free(PVOID pPtr, ULONG nSize)

{

       CAutoLock lock(&m_Lock);

 

       if (pPtr >= m_pPool && pPtr < m_pPool + m_nPoolSize)

       {

              if (nSize > m_nPoolSize - m_nHeader)

                     m_nHeader = 0;

 

              //必须按顺序回收

              ASSERT(pPtr == m_pPool + m_nHeader);

             

              m_nHeader += nSize;

              m_nPoolLeft += nSize;

       }else

       {

              delete [] pPtr;

              pPtr = NULL;

       }

      

}

阅读全文
0 0

相关文章推荐

img
取 消
img