首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Wumpus游戏的“城市边缘”功能会导致堆溢出。

Wumpus游戏的“城市边缘”功能会导致堆溢出。
EN

Stack Overflow用户
提问于 2015-04-12 13:26:09
回答 1查看 235关注 0票数 2

通过阅读Lisp之地的书,我成功地进入了Theft游戏,这个游戏让我定义了一个make-city-edges函数。然而,当我尝试运行它时,SBCL挂起一段时间,然后给出一个非常令人讨厌的错误:

代码语言:javascript
复制
    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> 

我已经仔细检查过了,看我是否犯了什么错误,但我找不到。

造成问题的函数如下:

代码语言:javascript
复制
(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)))

[这里]是代码的其余部分--如果您想查看其他函数,我将其添加到GitHub Gist页面,因为它占用了太多的问题空间。

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

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-04-13 18:09:11

在链接代码中,

代码语言:javascript
复制
(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可能会提供有用的回溯。

例如,回溯:

代码语言:javascript
复制
  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) ...)似乎是坏的。”

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/29589981

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档