www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Can't free memory allocated in a C DLL?

reply Johannes Pfau <spam example.com> writes:
This is a reduced problem encountered with DTagLib on windows:
TagLib allocates memory using malloc in a DLL compiled with MSVC (or
mingw). When I try to free this memory in D the free() call just freezes
infinitely. Here's the reduced test case:
http://dl.dropbox.com/u/24218791/d/BUG.zip

Before I file the bug: Can this even be fixed without using the MSVC
runtime in D? Seems like this problem is caused by the different C
runtimes (The same example works fine with GDC on windows).

I guess this is also the reason why most C libraries have their own
*_free functions?

-- 
Johannes Pfau
Aug 05 2011
next sibling parent reply Dmitry Olshansky <dmitry.olsh gmail.com> writes:
On 05.08.2011 14:10, Johannes Pfau wrote:
 This is a reduced problem encountered with DTagLib on windows:
 TagLib allocates memory using malloc in a DLL compiled with MSVC (or
 mingw). When I try to free this memory in D the free() call just freezes
 infinitely. Here's the reduced test case:
 http://dl.dropbox.com/u/24218791/d/BUG.zip
I was bitten by this an awful lot of times. In general freeing memory not where it's allocated is BAD. Even if it might work for code having the same runtime _version_ as DLL one, it's still like sitting on pile of dynamite.
 Before I file the bug: Can this even be fixed without using the MSVC
 runtime in D? Seems like this problem is caused by the different C
 runtimes (The same example works fine with GDC on windows).
Nope, different version of run-time has mildly different means for allocation/deallocation. Which may or may not result in a crush or memory corruption (recall that dynamite pile).
 I guess this is also the reason why most C libraries have their own
 *_free functions?
The only workable solution that I was able to come up with for this sort of problem - if DLL escapes references, provide a close/free/dispose function as well. -- Dmitry Olshansky
Aug 05 2011
parent Johannes Pfau <spam example.com> writes:
Dmitry Olshansky wrote:
On 05.08.2011 14:10, Johannes Pfau wrote:
 This is a reduced problem encountered with DTagLib on windows:
 TagLib allocates memory using malloc in a DLL compiled with MSVC (or
 mingw). When I try to free this memory in D the free() call just
 freezes infinitely. Here's the reduced test case:
 http://dl.dropbox.com/u/24218791/d/BUG.zip
I was bitten by this an awful lot of times. In general freeing memory not where it's allocated is BAD. Even if it might work for code having the same runtime _version_ as DLL one, it's still like sitting on pile of dynamite.
 Before I file the bug: Can this even be fixed without using the MSVC
 runtime in D? Seems like this problem is caused by the different C
 runtimes (The same example works fine with GDC on windows).
Nope, different version of run-time has mildly different means for allocation/deallocation. Which may or may not result in a crush or memory corruption (recall that dynamite pile).
 I guess this is also the reason why most C libraries have their own
 *_free functions?
The only workable solution that I was able to come up with for this sort of problem - if DLL escapes references, provide a close/free/dispose function as well.
Ok, thanks for this detailed answer. I've added a taglib_free function to TagLib's C binding and submitted a pull request. Hopefully it'll get merged. -- Johannes Pfau
Aug 05 2011
prev sibling parent reply Kagamin <spam here.lot> writes:
Johannes Pfau Wrote:

 This is a reduced problem encountered with DTagLib on windows:
 TagLib allocates memory using malloc in a DLL compiled with MSVC (or
 mingw). When I try to free this memory in D the free() call just freezes
 infinitely. Here's the reduced test case:
 http://dl.dropbox.com/u/24218791/d/BUG.zip
You can also try to free it from the default process heap.
Aug 05 2011
parent reply Johannes Pfau <spam example.com> writes:
Kagamin wrote:
Johannes Pfau Wrote:

 This is a reduced problem encountered with DTagLib on windows:
 TagLib allocates memory using malloc in a DLL compiled with MSVC (or
 mingw). When I try to free this memory in D the free() call just
 freezes infinitely. Here's the reduced test case:
 http://dl.dropbox.com/u/24218791/d/BUG.zip
You can also try to free it from the default process heap.
Thanks, the taglib_free function has already been merged into the official taglib git (that was quite fast ;-)) so the problem's solved. But out of curiosity:
You can also try to free it from the default process heap.
How is that done? GlobalFree? -- Johannes Pfau
Aug 05 2011
next sibling parent reply Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
Maybe HeapFree, MS says GlobalFree shouldn't be used anymore.
Aug 05 2011
parent Simon <s.d.hammett gmail.com> writes:
On 05/08/2011 19:00, Andrej Mitrovic wrote:
 Maybe HeapFree, MS says GlobalFree shouldn't be used anymore.
You can't use HeapFree to free memory allocated by the MS crt. And even it did happen to work you've no guarantee it would continue to work in future. You always have to use the free method which is appropriate for the method which allocated the memory in the first place. -- My enormous talent is exceeded only by my outrageous laziness. http://www.ssTk.co.uk
Aug 05 2011
prev sibling parent Kagamin <spam here.lot> writes:
Johannes Pfau Wrote:

 How is that done? GlobalFree?
HeapFree. msvcrt uses system functionality for memory management. The problem is it can create a separate heap and not use the default process heap probably in order to free memory easily on unload: it just destroys the heap and everything is freed. mingw builds usually use system built-in msvcrt.dll that uses the process default heap AFAIK.
Aug 05 2011