Suppose that I have a foreign function:
-- | Turns char* of the given size into a char* of size 16.
doSomethingFfi :: Ptr CUChar -> Ptr CUChar -> CSize -> IO ()
doSomethingFfi = undefined
这个函数是纯函数,因此我想在Haskell中表示它为纯函数:
doSomething :: ByteArray bytes => bytes -> bytes
doSomething bs = unsafePerformIO $
alloc 16 $ \outPtr ->
withByteArray bs $ \inPtr ->
doSomethingFfi outPtr inPtr (fromIntegral $ length bs)
(在这里我使用了来自memory
的alloc
。)
我理解unsafePerformIO
和unsafeDupablePerformIO
之间唯一的区别是后者中的IO操作可以在没有任何清理的情况下被静默地终止。
在我上面的例子中,基本上有两个IO操作:1、内存分配;2、外部调用。我不关心第二个,因为它是纯的,但我担心第一个。
如果计算被静默中断,这种方式分配的内存是否有任何保证不会泄漏?如果外部函数还需要我分配/清理临时存储,并且我使用alloca
来实现这个目的,那么使用unsafeDupablePerformIO
是否仍然安全?
alloca
在这种情况下应该是安全的,我相信。它在垃圾回收堆中分配固定内存,因此如果您的IO
被中止,它应该被清理。 - dfeueralloc
使用了malloc
分配的内存。它会附加一个finalizer以释放内存,但我认为您不能保证在计算被中止之前安装finalizer。 - dfeueralloc
可以为不同的类实例使用不同的分配策略。有些似乎使用malloc
;其他的我不确定。 - dfeueralloc
是一个类方法。我正在查看Bytes
的实现,你可能在查看其他东西。所以它也取决于实例... - kirelagin