This question is about the functions alloca
and malloc
from Foreign.Marshal.Alloc
and newForeignPtr
and mallocForeignPtr
from Foreign.ForeignPtr
. Where does the allocated memory live and how does the garbage collector treat it?
Haskell computations produce a lot of memory garbage - much more than conventional imperative languages. It's because data are immutable so the only way to store every next operation's result is to create new values. In particular, every iteration of a recursive computation creates a new value.
The Haskell runtime system employs a generational garbage collector (GC) with two generations 2. Generations are numbered starting with the youngest generation at zero.
The memory pointed to by Ptr a
allocated by malloc
lives on the heap, as in the C programming language. It is ignored by the garbage collector - you have to manually deallocate it yourself using free
, and be careful to never use it again after that.
alloca f
does a similar allocation, call f
with the pointer, and free the memory after that. The pointer must not be used after f
returns.
These routines are not meant to be used in everyday code, but only to interface with other languages, using a C-like interface (FFI). You get precisely the same memory safety guarantees C offers -- which means practically none. As such it is quite dangerous, and should be used with great care.
By comparison, the ForeignPtr
-pointed memory still lives on the heap, but will be garbage collected after no more pointers (i.e. Haskell's ForeignPtr a
) refer to the memory. Note that, even if garbage collection is used here, this kind of pointers are not risk-free. Indeed, when Haskell has no more live pointers to the memory the runtime will free it, even if that pointer is still live in the foreign language. The programmer must ensure that this will never happen.
malloc
calls the C malloc()
, so it allocates memory on the C heap which you have to free manually. (You can also do that from C with free()
if you like.)
alloca
and mallocForeignPtr
allocate pinned byte arrays, which live on the Haskell pinned heap. The GC will free these automatically when they're no longer needed, but will never move them (since they're pinned) so you can pass their addresses to a C function.
newForeignPtr
doesn't seem relevant to your question.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With