【发布时间】:2020-10-16 20:53:31
【问题描述】:
假设我有一个外部函数:
-- | 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.外呼。我不关心2,因为它是纯粹的,但是我担心内存。
如果计算被静默中断,是否可以保证以这种方式分配的内存不会泄漏?如果外部函数还需要我必须分配/清理的临时存储并且我为此使用了alloca,那么使用unsafeDupablePerformIO 是否仍然安全?
【问题讨论】:
-
这对我来说听起来很糟糕!您从
unsafePerformIO获得的性能不够好? -
我相信
alloca在这种情况下应该是安全的。它在垃圾收集堆中分配固定内存,因此如果您的IO被中止,则应该清理它。 -
@dfeuer 我没有对它进行基准测试,所以假设这个问题纯粹是学术问题:)。我只是想知道在这种情况下我应该使用哪个功能并注意到,例如
cryptoniteusesunsafeDupablePerformIO并开始怀疑这是否是个好主意。 -
我认为
alloc也分配了固定的垃圾收集内存。我的问题可以重新表述为“GHC 是否保证 GC 将收集由静默中止 IO 中的分配产生的内存”? -
啊,需要注意的是
alloc是一个类方法。我在看implementation forBytes,你可能在看别的东西。所以它也取决于实例......
标签: haskell memory memory-leaks unsafe-perform-io