title: How can I make data that is allocated manually be garbage-collected in Haskell?
body: <p>I'm thinking about a FFI calling some C functions from Haskell.</p>
  
  <p>If a memory buffer is used to hold some data and is allocated "manually" and then it is used in Haskell computations, can I somehow rely on the garbage collector to free it when it is not needed anymore.</p>
  
  <p>As for the manual allocations, there are basically two ways (but the difference doesn't seem to be essential for my question):</p>
  
  <ul>
  <li>allocating a buffer in Haskell, then passing it to C function, like in <a href="http://hackage.haskell.org/package/unix-2.7.1.0/docs/src/System-Posix-IO-Common.html#fdRead" rel="nofollow noreferrer"><code>fdRead</code></a></li>
  <li>allocating a buffer in C (with <code>malloc</code>, like in GNU's <a href="https://stackoverflow.com/q/28562512/94687"><code>asprintf</code></a>), then returning the pointer to Haskell</li>
  </ul>
  
  <p>In both examples (<code>fdRead</code> or <code>asprintf</code>) there is also a problem that the data type stored in the buffer is not suitable for a Haskell program, therefore it is copied&amp;converted to be used in Haskell (with <code>peekCString</code>). (I'll put the code below.) After the copying&amp;conversion happens, the buffer is freed (in both cases).</p>
  
  <p>However, I'm thinking about a more efficient interface, where the Haskell would directly use the data as it is stored by a C function (without a conversion). (I haven't yet explored, say, alternative implementations of <code>String</code> and related functions: whether there is one among them which can work directly with some kind of C strings.)</p>
  
  <p>If I follow this route, then there is one global problem: how to control the disposal of the allocated buffers. (For side-effects-free functions--except for the allocation--I could even wrap the calls in <code>unsafePerformIO</code> or declare them so that they are not an <code>IO</code>.)</p>
  
  <h2>Examples with conversion and immediate freeing</h2>
  
  <h3>allocating in Haskell:</h3>
  
  <p><a href="http://hackage.haskell.org/package/unix-2.7.1.0/docs/src/System-Posix-IO-Common.html#fdRead" rel="nofollow noreferrer">fdRead</a> (here <a href="http://hackage.haskell.org/package/base-4.7.0.2/docs/Foreign-Marshal-Alloc.html#v:allocaBytes" rel="nofollow noreferrer"><code>allocaBytes</code></a> must care for the freeing):</p>
  
  <pre><code>-- -----------------------------------------------------------------------------
  -- fd{Read,Write}
  
  -- | Read data from an 'Fd' and convert it to a 'String' using the locale encoding.
  -- Throws an exception if this is an invalid descriptor, or EOF has been
  -- reached.
  fdRead :: Fd
         -&gt; ByteCount -- ^How many bytes to read
         -&gt; IO (String, ByteCount) -- ^The bytes read, how many bytes were read.
  fdRead _fd 0 = return ("", 0)
  fdRead fd nbytes = do
      allocaBytes (fromIntegral nbytes) $ \ buf -&gt; do
      rc &lt;- fdReadBuf fd buf nbytes
      case rc of
        0 -&gt; ioError (ioeSetErrorString (mkIOError EOF "fdRead" Nothing Nothing) "EOF")
        n -&gt; do
         s &lt;- peekCStringLen (castPtr buf, fromIntegral n)
         return (s, n)
  
  -- | Read data from an 'Fd' into memory.  This is exactly equivalent
  -- to the POSIX @read@ function.
  fdReadBuf :: Fd
            -&gt; Ptr Word8 -- ^ Memory in which to put the data
            -&gt; ByteCount -- ^ Maximum number of bytes to read
            -&gt; IO ByteCount -- ^ Number of bytes read (zero for EOF)
  fdReadBuf _fd _buf 0 = return 0
  fdReadBuf fd buf nbytes =
    fmap fromIntegral $
      throwErrnoIfMinus1Retry "fdReadBuf" $
        c_safe_read (fromIntegral fd) (castPtr buf) nbytes
  
  foreign import ccall safe "read"
     c_safe_read :: CInt -&gt; Ptr CChar -&gt; CSize -&gt; IO CSsize
  </code></pre>
  
  <h3>allocating in C</h3>
  
  <p><code>getValue.c</code>:</p>
  
  <pre><code>#define _GNU_SOURCE
  #include &lt;stdio.h&gt;
  
  #include "getValue.h"
  
  char * getValue(int key) {
    char * value;
    asprintf(&amp;value, "%d", key); // TODO: No error handling!
    // If memory allocation wasn't possible, or some other error occurs,  these  functions  will
    // return -1, and the contents of strp is undefined.
    return value;
  }
  </code></pre>
  
  <p><code>GetValue.hs</code> (here I explicitly call <code>free</code> after the conversion <a href="https://stackoverflow.com/a/1739331/94687">is actually done</a>):</p>
  
  <pre><code>{-# LANGUAGE ForeignFunctionInterface #-}
  
  import Foreign hiding (unsafePerformIO)
  import Foreign.Ptr
  import Foreign.C.Types
  
  import Foreign.C.String(peekCString)
  
  import System.IO.Unsafe
  
  getValue :: Int -&gt; IO String
  getValue key = do
    valptr &lt;- c_safe_getValue (fromIntegral key)
    value &lt;- peekCString valptr
    c_safe_free valptr
    return value
  
  foreign import ccall safe "getValue.h getValue" c_safe_getValue :: CInt -&gt; IO (Ptr CChar)
  foreign import ccall safe "stdlib.h free" c_safe_free :: Ptr a -&gt; IO ()
  
  value :: Int -&gt; String
  value = unsafePerformIO . getValue -- getValue has no side-effects, so we wrap it.
  
  {- A simple test: -}
  main1 = putStrLn (value 2)
  
  {- A test with an infinite list, which employs laziness: -}
  keys = [-5..]
  results = map value keys
  
  main = foldr (&gt;&gt;) 
               (return ())
               (map putStrLn (take 20 results))
  </code></pre>
  
  <p>If there wasn't the (ineffective) conversion&amp;copying step, I would need to rely on garbage collector for freeing, but have no idea how to define such things in Haskell.</p>