我正在学习如何使用Haskell的C FFI。
假设我正在调用一个创建对象并返回指向该对象指针的C函数。我可以使用free
从Haskell运行时中释放这个内存吗?(我指的是Haskell的free
而不是C的free
)
考虑以下代码:
{-# LANGUAGE ForeignFunctionInterface #-}
module Main where
import Prelude hiding (exp)
import Foreign.Marshal.Alloc
import Foreign.Storable
import Foreign.C.Types
import Foreign.Ptr
import Foreign.Marshal.Array
foreign import ccall "get_non_freed_array" c_get_non_freed_array :: CInt -> IO (Ptr CInt) -- An array initialized
main :: IO()
main = do
let numelements = 5
ptr <- c_get_non_freed_array numelements
w0 <- peek $ advancePtr ptr 0
w1 <- peek $ advancePtr ptr 1
w2 <- peek $ advancePtr ptr 2
w3 <- peek $ advancePtr ptr 3
w4 <- peek $ advancePtr ptr 4
print [w0, w1, w2, w3, w4]
return ()
我已经写了一段 C99 中的代码,其中有一个名为 get_non_freed_array
的函数,它的内容如下:
#include "test.h"
#include <stdlib.h>
// return a memory block that is not freed.
int* get_non_freed_array(int n)
{
int* ptr = (int*) malloc(sizeof(int)*n);
for(int i=0 ; i<n ; ++i){
ptr[i] = i*i;
}
return ptr;
}
(
test.h
中只包含一个单行,其中包含Haskell的FFI访问get_non_freed_array
函数的函数签名。)我感到困惑,因为我不知道C运行时分配的内存在从Haskell运行时调用后“完成”运行时是否进行垃圾回收。我的意思是,如果是另一个C函数调用它,那么我知道内存将是安全的,但由于Haskell函数调用了
get_non_freed_array
,我不知道这是否仍然成立。尽管上述Haskell代码打印出正确的结果,但我不知道通过
ptr
返回的内存是否安全可用。如果是安全的,我们可以从Haskell本身释放这个内存吗?还是我必须编写另一个C函数,比如,在test.c中编写
destroy_array(int* ptr)
,然后从Haskell调用它?
编辑:简而言之,我需要更多有关在Haskell中编写代码时如何处理在C函数中创建的对象指针的信息。
free
函数?有文档参考吗?编辑:算了,它在这里:http://downloads.haskell.org/~ghc/8.0.1-rc2/docs/html/libraries/base-4.9.0.0/Foreign-Marshal-Alloc.html#v:free - Eugene Sh.alloca
等函数和C类型很好用。一旦你开始编写更为复杂的C类型的Haskell版本(用于分配内存),我发现bindings-DSL包可以提供很多帮助(同时在使用上非常简单且没有任何魔法)。 - gspr