Question

Is it possible to take a heap handle from HeapCreate() and set all available memory to a certain value?

I've tried enumerating the heap by region and setting it that way, but I get access violations.

I basically want to set the memory in my heap to a custom value that I can use for debugging, before it's ultimately destroyed via HeapDestroy.

Was it helpful?

Solution

The short answer is "no, you can't fill the heap with a specific value".

You could wrap your heap access functions with debug versions, for example

// In some header file
#define HeapAlloc(a, b, c) MyHeapAlloc(a, b, c, __FILE__, __LINE__)
#define HeapFree(a, b, c) MyHeapFree(a, b, c, __FILE__, __LINE__)

... 

// In a separate source file:

#ifdef HeapAlloc
#undef HeapAlloc
#undef HeapFree
#endif

struct extra
{
    extra *next;
    size_t size;
    const char *file;
    int line;
};

extra* head;

LPVOID MyHeapAlloc(HANDLE heap, DWORD flags, SIZE_T size, const char *file, int line)
{
    LPVOID res = HeapAlloc(heap, flags, size + sizeof(extra));
    if (!res)
    {
        cout << "Allocation failed, called from " << file << ":" << line << endl;
        return 0;
    }

    extra *p = reinterpret_cast<extra*>(res);
    res = reinterpret_cast<void*>(&p[1]); 

    p->next = head;
    p->size = size;
    p->file = file;
    p->line = line;

    memset(res, 0xAA, size); 
    return res;
}

BOOL MyHeapFree(HANDLE heap, DWORD flags, LPVOID mem, const char *file, int line)
{
    extra *p = reinterpret_cast<extra*>(mem);
    p = reinterpret_cast<void*>(&p[-1]); 

    extra *q = head;
    extra *prev = 0;
    while(q)
    {
        if (reinterpret_cast<void*>(&q[1]) == mem)
        {
            break;
        }
        prev = q;
        q = next;
   }
   if (!q)
   {
       cout << "Attempt to free memory that wasn't allocated from " << file << ":" << line << endl;
       return false; 
   }

   /* Unlink q - if prev = NULL then it's the first one, so just move head */
   if (prev)
   {
      prev->next = q->next;
   }
   else
   {
      head = q->next;
   }

   memset(mem, 0xBB, q->size);
   return HeapFree(heap, flags, reinterpret_cast<void *>(q); 
}

I have just typed all that in, so there may be minor typos, but hopefully it shows you a method of dealing with memory allocations. For some case, you may have to pad the extra struct to be a multiple of 16 or 32 bytes to ensure alignment of the following data. You can of course, at any time, dump the linked list pointed to by head, to see what is allocated.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top