做这类事情的系统方法是通过 CPS 转换。以下实现的特别之处在于,在调用 intsqrt_cps 期间分配的每个内存字节在调用返回后都会被释放。这里没有 GC(与上面的 Haskell 解决方案不同):
fun
intsqrt_cps
(
n: int, k: int -<lincloptr1> int
) : int =
if
(n >= 1)
then let
val n4 = n / 4
in
//
intsqrt_cps
( n4
, llam(res) =>
applin(k, if square(2*res+1) <= n then 2*res+1 else 2*res)
) (* intsqrt_cps *)
//
end // end of [then]
else applin(k, 0) // end of [else]
fun intsqrt(n:int): int = intsqrt_cps(n, llam(x) => x)
完整的代码可以在以下位置找到:
https://github.com/githwxi/ATS-Postiats/blob/master/doc/EXAMPLE/MISC/intsqrt_cps.dats
您可以使用 valgrind 来验证是否存在内存泄漏:
==28857== Memcheck, a memory error detector
==28857== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==28857== Using Valgrind-3.11.0 and LibVEX; rerun with -h for copyright info
==28857== Command: ./intsqrt_cps.exe
==28857==
intsqrt(1023) = 31
intsqrt(1024) = 32
==28857==
==28857== HEAP SUMMARY:
==28857== in use at exit: 0 bytes in 0 blocks
==28857== total heap usage: 14 allocs, 14 frees, 1,304 bytes allocated
==28857==
==28857== All heap blocks were freed -- no leaks are possible
==28857==
==28857== For counts of detected and suppressed errors, rerun with: -v
==28857== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)