windows核心编程学习笔记(五.续)堆

时间:2021-06-03 20:41:28
堆(Heap)和栈(Stack)不同,堆是给进程用的,用来存储各个线程申请的内存块。
不能同时在堆上进行Alloc操作,这就意味这如果2个线程同时执行new操作,那么一个可以执行,另一个要等到这个执行完毕才可以执行new——否则的话,可能返回同一个地址,而线程还傻乎乎的以为是不同的呢。因此,如果想获取高效率而不出现问题(当然还有其他原因),那么可以另外创建一个堆来使用。使用函数 HeapCreate来创建一个堆。
    从堆中分配内存:HeapAlloc
    改变已分配内存大小:HeapReAlloc
    获取已分配内存块大小:HeapSize
    释放已分配内存块:HeapFree
    销毁堆:HeapDestroy
可是,此时使用new操作符,仍将在默认的堆上分配空间,我们需要在新的堆上来分配空间,此时需要重载对应类的new和delete操作符。
class  CSomeClass 
{
private :
   
static  HANDLE s_hHeap;
   
static  UINT s_uNumAllocsInHeap;
   
//  Other private data and member functions
public :
   
void *   operator   new  (size_t size);
   
void   operator  delete ( void *  p);
   
//  Other public data and member functions
};

HANDLE CSomeClass::s_hHeap 
=  NULL;
UINT CSomeClass::s_uNumAllocsInHeap 
=   0 ;

void *  CSomeClass:: operator   new  (size_t size)
{
   
if (s_hHeap  ==  NULL)
   {
      
//  Heap does not exist; create it.
      s_hHeap  =  HeapCreate(HEAP_NO_SERIALIZE,  0 0 );

      
if (s_hHeap  ==  NULL)
         
return (NULL);
   }
   
//  The heap exists for CSomeClass objects.
    void *  p  =  HeapAlloc(s_hHeap,  0 , size);

   
if (p  !=  NULL) 
   {
      
//  Memory was allocated successfully; increment
      
//  the count of CSomeClass objects in the heap.
      s_uNumAllocsInHeap ++ ;
   }

   
//  Return the address of the allocated CSomeClass object.
    return (p);
}
void  CSomeClass:: operator  delete ( void *  p) 
{
   
if (HeapFree(s_hHeap,  0 , p))
   {
      
//  Object was deleted successfully.
      s_uNumAllocsInHeap -- ;
   }

   
if (s_uNumAllocsInHeap  ==   0 )
   {
      
//  If there are no more objects in the heap,
      
//  destroy the heap.
       if (HeapDestroy(s_hHeap))
      {
         
// Set the heap handle to NULL so that the new operator
         
// will know to create a new heap if a new CSomeClass
         
// object is created.
         s_hHeap  =  NULL;
      }
   }
}

本章末尾讲解了其他堆操作函数,但用途似乎不大,可以选看。