如何在lisp中分配内存块

时间:2011-04-17 01:55:09

标签: common-lisp

in clisp

(eq (cons 'a 'b) (cons 'a 'b)) 

是假(NIL)
因为第一个(AB)和第二个(AB)分配在不同的内存中。

(eq 'a(car '(a b c)))

是真的(T)

然而,为什么?
像两个(AB),第一个A和第二个A是由(car'(a b c))产生的,必须使用不同的记忆吗? 如何在clisp中分配内存块?

4 个答案:

答案 0 :(得分:4)

对CONS的每次调用都会创建一个新的cons小区。这些是不同的对象。

(eq (cons 1 2) (cons 1 2)) - > NIL

具有相同名称的符号是相同的对象。

(eq 'foo 'foo) -> T

并发症

具有相同名称但在不同中的符号是不同的对象。

(eq 'bar::foo 'baz::foo) -> NIL

没有包的同名符号可能是同一个对象。

(eq '#:foo '#:foo) -> NIL

(let ((sym '#:foo))
   (eq sym sym))
-> T

答案 1 :(得分:3)

这是因为'a是实习生。也就是说,无论何时在代码中键入'a(在第二个示例中,它出现两次),它们将解析为相同的符号。这是因为读者将使用INTERN函数获得对符号的引用。 (Hyperspec docs)。

这就是(eq 'a 'a)返回T的原因。但是有一个例外。前缀为#:的符号永远不会被实现。 GENSYM使用此功能来保证在编写宏时获得唯一的符号。

答案 2 :(得分:1)

CONS创建对。在您的具体示例中,两对都包含符号A和B.

通常,您不必担心在Common Lisp中分配内存块,而是创建结构(数组,列表,类,哈希表)。你唯一一次分配内存bnlock就是为了调用从另一种语言链接的函数。

答案 3 :(得分:1)

符号是特殊对象。当Common Lisp首次遇到符号时,它会被实现,即创建一个表示符号的对象,并将符号映射到该对象。对于该符号的所有进一步引用,使用符号名称作为键来检索此对象。例如,假设Common Lisp在符号a的内存位置0x05处创建了一个对象。对a的所有进一步引用都将指向同一个对象。这意味着(eq 'a 'a)基本上变为(eq 0x05 0x05),其评估为T

cons的情况有所不同。每次调用cons都会在内存中创建一个新对象。第一次调用cons会在位置0x10创建一个对象,在0x20创建第二个调用。因此,您的第一次比较变为(eq 0x10 0x20),返回nil。对的组件可以指向相同的对象,但对本身指向不同的位置。