为什么局部变量没有被释放



测试功能如下:

(defun fab (n) 
(let ((res '(1 1)))
(loop for i from 2 to n do
(nconc res (list (+ (nth (- i 2) res) (nth (- i 1) res)))))
res))

$ecl

EECL(嵌入式公共Lisp)12.7.1(git:UNKNOWN)

>(fab 10)
(1 1 2 3 5 8 13 21 34 55 89)
>(fab 20)
(1 1 2 3 5 8 13 21 34 55 89 2 3 5 8 13 21 34 55 89 144 91 5 8 13 21 34 55 89 144

然后我重新启动ECL

>(fab 20)
(1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181 6765 10946)

似乎"res"在(fac 10)之后没有被释放?

真诚!

let形式中应该使用(list 1 1)而不是'(1 1)。在Common Lisp中,没有定义修改文本对象的效果。

(defun fib (n)
(let ((res (list 1 1))) ; (list 1 1) instead of '(1 1)
(loop for i from 2 to n
do (nconc res (list (+ (nth (- i 2) res) (nth (- i 1) res)))))
res))

编译器/解释器只分配一次常量,如'(1 1)。您的代码在此列表中使用NCONC,修改后,后续调用将不再看到常量列表"(11)",而是修改后的列表。在Common Lisp中,未指定当打开时破坏性地修改常量表达式时会发生什么,有些实现甚至保护它们不受更改的影响,以避免此类意外。如果你需要一个新的常数,按照人们说的去做并使用(列表1 1),或者完全避免使用NCONC。

相关内容

  • 没有找到相关文章

最新更新