HeapAlloc fails intermittently

2.8k Views Asked by At

We have a DLL (built using VC2005) that does some processing on behalf of the calling application. This processing requires quite a bit of memory. The DLL creates this memory via heapAlloc like so:

//Allocate space
myStruct* pStackSpace = (myStruct*)::HeapAlloc(m_hStackHeap, 0, sizeof(myStruct));

...
do some processing here
...

//Free space
::HeapFree(m_hStackHeap, 0, pStackSpace);

The heap is allocated via:

m_hStackHeap = ::HeapCreate(0, sizeof(myStruct)*10, 0);

After the create we actually allocate 20 myStructs and then free them just to make sure it handle that. So we know there is enough space.

The issues is that in some case HeapAlloc returns NULL. If that happens we do a HeapValidate(m_hStackHeap, 0, NULL) which always comes back nonezero (meaning all is well). So we know the heap is ok.

We also grantee that we never have more then 10 concurrent allocation at the same time so there should be enough space since the initial heapCreate reserved that much.

The next call to HeapAlloc often succeeds. The behavior is very sporadic. It will work fine, then fail to allocate a few times and then start working fine again.

Any ideas on what is going on?

3

There are 3 best solutions below

0
On

Rather than use a custom heap you can use custom ALLOC and FREE routines that keep a pool of the appropriate size.

This is done with unioning the struct with a simple object containing a NEXT pointer and one global variable containing a pointer.

If you're out allocate a new one from the global heap.

Where you would have destroyed the heap free all these.

2
On

2mb structs? Consider using VirtualAlloc and a alloc/free pointer list.

8
On

The behavior suggests it could be due to heap fragmentation. You may have sufficient total heap space to satisfy the request but no free blocks large enough. Try using a Low Fragmentation Heap. You can do that by calling HeapSetInformation() to enable LFH. Note that you can't use LFH if you specified the HEAP_NO_SERIALIZE flag in HeapCreate().