El problema es que el HEAP usado es diferente. Cada libreria CRT (C Run Time) suele llamar a HeapCreate al iniciarse y su malloc usa ese HEAP devuelto. Para comprobarlo podes hacer una prueba como esta:
En tu DLL, reservar con HeapAlloc y para el HEAP usas
GetProcessHeap asi no usas un HEAP privado sino el del proceso por defecto. Ej.
char *mem = (char*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY /*no hace falta usar ZeroMemory a mano*/, size);
En tu programa, liberas con HeapFree y obviamente el mismo HEAP anterior. Ej.
HeapFree(GetProcessHeap(), 0, mem);