Creating Your Own Heaps

< BACK  NEXT >
[oR]

You should consider creating your own heap for memory allocation if you want to do either of the following:

  • Make lots of memory allocations that will all be deleted at the same time

  • Make lots of memory allocations of the same size

As described earlier, the default heap cannot be deleted, and so fragmentation can cause memory problems if the process executes over a long period of time. By using your own heaps, you can delete the heap periodically and therefore effectively remove fragmentation and memory wastage.

A new heap can be created using the function HeapCreate. This function is passed a serialization option, the initial size for the heap, and the maximum size of heap. All heaps are serialized and the initial size and maximum size are ignored. This code returns a handle to the new heap:

 HANDLE hHeap; hHeap = HeapCreate(0, 1024, 0); 

Once a heap has been created, allocations can be made using the HeapAlloc function. For example, the following code allocates space for 100 Unicode characters and places NULLs in each byte.

 LPTSTR lpStr; lpStr = (LPTSTR) HeapAlloc(hHeap,     HEAP_ZERO_MEMORY,     100 * sizeof(TCHAR)); if(lpStr == NULL)   cout   _T("Out of memory"); 

The function returns a valid handle on success, or a NULL if an out-of-memory condition results. All the functions that manipulate heaps, except HeapCreate, take a handle to the heap as the first argument. These functions can be used on the default process heap by calling the GetProcessHeap function to return a handle to the default process heap.

The function is passed the handle to the heap returned from HeapCreate, a flag (the only flag used in Windows CE is HEAP_ZERO_MEMORY), and the number of bytes to allocate. The number of bytes allocated may be larger than the number requested, and these extra bytes can be used by the application (although this would not be considered good practice). The HeapSize function can be used to return the actual size of the allocation. It is passed thehandle to the heap, flags (which are always 0 with Windows CE), and the pointer to the allocation:

 DWORD dwSize; dwSize = HeapSize(hHeap, 0, lpStr); 

An allocation can be freed using the HeapFree function, which is passed the handle to the heap, flags (0 for Windows CE), and the pointer to the allocation to be freed:

 if(!HeapFree(hHeap, 0, lpStr))   cout   _T("Allocation could not be freed"); 

A memory allocation can be reallocated to a different size through calling the HeapRealloc function. You need to be careful calling this function, since the reallocation may result in the memory block being moved. This results in a new pointer being returned. Finally, a heap can be deleted by calling the HeapDestroy function. You do not have to delete each individual allocation before calling this function. The HeapDestroy function is simply passed the handle to the heap:

 if(!HeapDestroy(hHeap))   cout   _T("Could not destroy heap"); 

Using Heaps with C++ Classes

You can use a separate heap for allocating objects for a given C++ class by overloading the new and delete operators. This is particularly useful if you are going to allocate large numbers of objects of one particular class. In the following code a C++ class called "cHeap" is declared that has a member variable called szBuffer, and this is used to store a Unicode string. Whenever a new object of the cHeap class is allocated, the allocation for the entire class object will be made from a separate heap, and the allocation will be handled using the overloaded new and delete operators declared in the class:

 class cHeap { public:   cHeap();   ~cHeap();   void* operator new(size_t size);   void operator delete(void* p);   void putStr(LPTSTR){ wcscpy(szBuffer, pStr);}   LPTSTR getStr() { return szBuffer;} private:   static HANDLE hHeap;   static int nCount;   TCHAR szBuffer[1024]; }; 

The static member "hHeap" will be used to store the handle to the separate heap, and nCount records the number of instances of this heap in existence. The implementation of cHeap declares the static variables hHeap and nCount:

 HANDLE cHeap::hHeap; int cHeap::nCount; 

The constructor and destructor for this class increment and decrement nCount:

 cHeap::cHeap() {   nCount++; } cHeap::~cHeap() {   nCount--; } 

The overloaded new operator first checks whether the separate heap has been allocated, and if not, creates it. The new operator then goes on to allocate the space for the new class object using the HeapAlloc function. The delete operator frees the given class object, and if the object count is zero, deletes the heap as well.

 void* cHeap::operator new(size_t size) {   if (hHeap == NULL)   {     hHeap = HeapCreate(0, 1024, 0);     if(hHeap == NULL)       cout   _T("Cannot create heap!");   }   return HeapAlloc(hHeap, HEAP_ZERO_MEMORY, size); } void cHeap::operator delete(void* p) {   HeapFree(hHeap, 0, p);   if(nCount = 0 && hHeap != NULL)   {     HeapDestroy(hHeap);     hHeap = NULL;   } } 

Objects of this "cHeap" class can now be allocated with the new operator, and the memory allocation for the object will be made from the separate heap rather than from the default process heap.

 cHeap* theObj = new cHeap(); // Use theObj pointer delete theObj; 

Note that if the variable is declared rather than dynamically allocated, the space used will be allocated from the stack if declared in a function:

 cHeap myObj;  // not allocated from separate heap 

< BACK  NEXT >


Windows CE 3. 0 Application Programming
Windows CE 3.0: Application Programming (Prentice Hall Series on Microsoft Technologies)
ISBN: 0130255920
EAN: 2147483647
Year: 2002
Pages: 181

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net