2015-04-12 32 views
2

通过Lisp的土地书,我设法去了侠盗猎魔游戏,这让我定义了一个make-city-edges函数。当我尝试但运行它,SBCL挂起了一会儿给我一个很讨厌的错误说Wumpus游戏的制作城市边缘功能导致堆溢出

Heap exhausted during garbage collection: 0 bytes available, 16 requested. 
Gen StaPg UbSta LaSta LUbSt Boxed Unboxed LB LUB !move Alloc Waste Trig WP GCs Mem-age 
    0:  0  0  0  0  0  0  0  0  0  0  0 10737418 0 0 0.0000 
    1:  0  0  0  0  0  0  0  0  0  0  0 10737418 0 0 0.0000 
    2: 27757  0  0  0 19204 70  0 10 54 631392704 505408 2000000 0 0 0.9800 
    3:  0  0  0  0  0  0  0  0  0  0  0 2000000 0 0 0.0000 
    4:  0  0  0  0  0  0  0  0  0  0  0 2000000 0 0 0.0000 
    5:  0  0  0  0  0  0  0  0  0  0  0 2000000 0 0 0.0000 
    6:  0  0  0  0 1638 251  0  0  0 61898752  0 2000000 1523 0 0.0000 
    Total bytes allocated = 1073069936 
    Dynamic-space-size bytes = 1073741824 
GC control variables: 
    *GC-INHIBIT* = true 
    *GC-PENDING* = true 
    *STOP-FOR-GC-PENDING* = false 
fatal error encountered in SBCL pid 85448(tid 140735276667664): 
Heap exhausted, game over. 

Error opening /dev/tty: Device not configured 
Welcome to LDB, a low-level debugger for the Lisp runtime environment. 
ldb> 

之前,我已经三检查,看看是否我没有犯错,但我找不到任何。

下面是导致问题的功能:

(defun make-city-edges() 
    (let* ((nodes (loop for i from 1 to *node-num* 
         collect i)) 
     (edge-list (connect-all-islands nodes (make-edge-list))) 
     (cops (remove-if-not (lambda (x) 
           (zerop (random *cop-odds*))) 
           edge-list))) 
    (add-cops (edges-to-alist edge-list) cops))) 

[here]是代码的其余部分,如果你想看看其他的功能,我把它添加到GitHub的要点页面,因为它会在这个问题上占用太多空间。

我能做些什么来解决这个问题?我在OSX 10.9上使用Emacs 24.4 (9.0),SLIMESBCL 1.2.10

+0

如果没有可重复的测试用例,平台,sbcl版本等,这可能无法诊断。 –

+0

@RainerJoswig你建议我做什么? –

+1

那么目前这个问题是否假设我们拥有所有这本书的“lisp的土地”,这本书是一本很棒的书,但是没有完整的代码,你会限制那些可以回答这个问题的人。目前只有拥有这本书并且想要重做练习的人才能够帮助...也许可以在这里或者在这里链接到一个要点。它需要完成,这样任何人都可以为你编译和测试。 – Baggers

回答

2

在链接代码,

(defun find-islands (nodes edge-list) 
    "returns a list of nodes that aren't interconnected" 
    (let ((islands nil)) 
    (labels ((find-island (nodes) 
      (let* ((connected (get-connected (car nodes) edge-list)) 
       (unconnected (set-difference nodes connected))) 
     (push connected islands) 
     (when connected 
      (find-island unconnected))))) 
     (find-island nodes)) 
    islands)) 

(when connected(when unconnected

用于调试堆耗尽的一些技巧:

  1. 检查您的循环和递归实际上终止。 (这就是我们找到这个解决方案的原因 - get-connected永远不会返回零,因此find-island会永久递归。)
  2. CL的trace可能很有用,以及传统的打印语句的添加。
  3. C-c C-c SLIME程序运行一段时间后,堆耗尽之前可能会提供一个有用的回溯。

例如,回溯的:

0: ((:INTERNAL TRAVERSE GET-CONNECTED) NIL) 
     Locals: 
     NODE = NIL 
     #:G11908 = ((2 . 21) (20 . 22) (22 . 20) (9 . 28) (28 . 9) (2 . 7) ...) 
     EDGE-LIST = ((8 . 3) (3 . 8) (18 . 7) (7 . 18) (26 . 23) (23 . 26) ...) 
     VISITED = (NIL) 
    1: (GET-CONNECTED NIL ((8 . 3) (3 . 8) (18 . 7) (7 . 18) (26 . 23) (23 . 26) ...)) 
     Locals: 
     NODE = NIL 
     EDGE-LIST = ((8 . 3) (3 . 8) (18 . 7) (7 . 18) (26 . 23) (23 . 26) ...) 
     VISITED = (NIL) 
    2: ((:INTERNAL FIND-ISLAND FIND-ISLANDS) NIL) 
     Locals: 
     NODES = NIL 
     ISLANDS = ((NIL) (NIL) (NIL) (NIL) (NIL) (NIL) ...) 
     EDGE-LIST = ((8 . 3) (3 . 8) (18 . 7) (7 . 18) (26 . 23) (23 . 26) ...) 
    3: (FIND-ISLANDS (1 2 3 4 5 6 ...) ((8 . 3) (3 . 8) (18 . 7) (7 . 18) (26 . 23) (23 . 26) ...)) 
     Locals: 
     NODES = (1 2 3 4 5 6 ...) 
     EDGE-LIST = ((8 . 3) (3 . 8) (18 . 7) (7 . 18) (26 . 23) (23 . 26) ...) 
     ISLANDS = ((NIL) (NIL) (NIL) (NIL) (NIL) (NIL) ...) 

可能导致我们说:“我没想到一个node将永远是nil,并islands((nil) (nil) (nil) ...)似乎打破。”