garbage collection and Ptr/ForeignPtr/StablePtr

Should I expect that Ptr memory allocated with malloc is garbage collected when no longer used by the Haskell runtime? The FFI spec doesn't say so explicitly (that I could see); AFAICT this is how the pointer types behave: Ptr : freed when no longer used/referenced ForeignPtr : like Ptr, but will also run a finaliser when freed StablePtr : not freed or collected (I haven't tested this; I've only read the FFI spec.) ***************************************************************** The information in this email and in any attachments is confidential and intended solely for the attention and use of the named addressee(s). This information may be subject to legal professional or other privilege or may otherwise be protected by work product immunity or other legal rules. It must not be disclosed to any person without our authority. If you are not the intended recipient, or a person responsible for delivering it to the intended recipient, you are not authorised to and must not disclose, copy, distribute, or retain this message or any part of it. *****************************************************************

On Monday 22 September 2003 12:10 pm, Bayley, Alistair wrote:
Should I expect that Ptr memory allocated with malloc is garbage collected when no longer used by the Haskell runtime? The FFI spec doesn't say so explicitly (that I could see);
C programs use pointers in many ways: pointers to static objects, pointers to stack-allocated objects, etc. as well as pointers to malloc-allocated objects. These are all represented with a 'Ptr' in Haskell but only one of them should be freed. Also, there are many ways to free a malloced object in C programs. You might have to decrement a reference count, you might have to first free any objects it contains pointers to, you might call a library-specific free routine called 'xfree', you might call a type-specific freeing routine or you might just call free. For all these reasons, Haskell's garbage collector cannot just call 'free' for you.
AFAICT this is how the pointer types behave: Ptr : freed when no longer used/referenced
No. If it needs freed, you have to explicitly deallocate this by calling an appropriate routine. This effectively means that you use Ptr for things accessed inside the IO monad.
ForeignPtr : like Ptr, but will also run a finaliser when freed
Yes. The finalizer is (a pointer to) any C function you like. ForeignPtr is especially useful for datatypes accessed outside the IO monad. e.g., if you wanted to use a complex number library, you might use ForeignPtr for the freeing function. ForeignPtr is also useful even if you are in the IO monad when you don't have a simple access pattern like 'allocate; use; free;'. Note that the ffi libraries provide functions called 'malloc' and 'free' and a finalizer called 'finalizerFree'. It is tempting to think that these are the C library 'malloc'/'free' and (a pointer to) 'free'. This is not necessarily so and you must take care that: - you only use MarshallAlloc.free and MarshallAlloc.finalizerFree with memory allocated using MarshallAlloc.malloc - you only use libc's 'free' with memory allocated using libc's 'malloc'.
StablePtr : not freed or collected
Yes. StablePtrs are in a different category because they are pointers from C into Haskell (in contrast, Ptrs and ForeignPtrs are pointers from Haskell into C). Since C doesn't have garbage collection, it is up to your C code to explicitly call 'freeStablePtr'.
(I haven't tested this; I've only read the FFI spec.)
I had a quick reread of sections 5.4 and 5.5 and I think your confusion is understandable. It doesn't say anything about deallocation so you might plausibly guess that the story is the same as for Int8 (say) which also says nothing about deallocation. ForeignPtrs are contrasted with Ptrs but only in whether or not they have finalizers. I think the ffi spec has now been finalized so it's too late to fix this but perhaps the next revision could include the following wording (inserted after the first sentence of section 5.4). Objects of type 'Ptr a' and 'FunPtr a' are garbage collected in the normal way but the objects they _point to_ are not garbage collected. If the objects pointed to require deallocation, this must be done by explicitly calling an appropriate function such as the C library function 'free'. I have put some of the above in my FFI guide at: http://www.reid-consulting-uk.ltd.uk/docs/ffi.html -- Alastair Reid www.haskell-consulting.com
participants (2)
-
Alastair Reid
-
Bayley, Alistair