The difference is in debug mode it calls the memory tracking version of calloc and in release it calls HeapAlloc. These two are vastly different and require different, corresponding release functions. Also, using the malloc/calloc family does not require you to create a heap first as HeapAlloc does. Here's what microsoft has to say about them :
Comparing Memory Allocation Methods | Microsoft Docs[
^]
Personally, unless I had to I would stay with the malloc family of calls (new/delete for c++) so I could take advantage of the memory tracking functionality that is available with them.
If you MUST use HeapAlloc here is a handy little template class that can help you with it. The nice thing is it automatically releases the memory when the object is deleted and provides operators that remove the need for casting of the pointer. It uses the global heap so you don't have to create one. Anyway, here it is:
template <typename T> class CHeapAlloc
{
public:
CHeapAlloc( size_t count = 1 )
{
size_t size = count * sizeof( T );
m_ptr = (T *)::HeapAlloc( ::GetProcessHeap(), HEAP_ZERO_MEMORY, size );
}
virtual ~CHeapAlloc()
{
if( m_ptr )
{
::HeapFree( ::GetProcessHeap(), 0, m_ptr );
m_ptr = nullptr;
}
}
operator T*() { return m_ptr; }
T * operator->() { return m_ptr; }
public:
T * m_ptr;
};
I can't remember where I found this but I think it came from here.