为什么本地变量没有被释放?

时间:2012-09-21 00:46:51

标签: common-lisp ecl

测试功能如下:

(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(Embeddable Common-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)之后没有被释放?

此致!

2 个答案:

答案 0 :(得分:4)

您应该在(list 1 1)表单中使用'(1 1)而不是let。在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)

诸如'(1 1)之类的常量仅由编译器/解释器分配一次。您的代码在此列表中使用NCONC,修改,后续调用不再看到常量列表'(1 1),而是修改后的列表。在Common Lisp中,未指定在破坏性地修改常量表达式时会发生什么,并且一些实现甚至保护它们免受更改以避免此类意外。如果您需要一个新的常量,请按照人们的说法和使用(列表1 1)或完全避免使用NCONC。