Ocaml“内存溢出”异常;详细模式显示“结构比较中的堆栈溢出”

5
一个来自外星的巨大的OCaml程序需要修复。其中一个问题是,程序在看似无害的一行代码崩溃了:
Hashtbl.mem loc_to_no loc

出现“内存不足”异常。问题在于肯定有足够的内存,而且对于其他输入甚至在处理问题之前,这行代码也能正常执行。

使用OCAMLRUNPARAM="v=63"运行它后,我看到在崩溃之前打印了一行:

结构比较中的堆栈溢出

涉及的结构如下所示。loc的类型为location

type ('a, 'b, 'c) automaton = {
  aut_id : int ;               
  mutable start_location : (('a, 'b, 'c) location) option ;
  mutable end_location   : (('a, 'b, 'c) location) option ;
  mutable aut_attributes : 'a ;                            
}
and ('a, 'b, 'c) location = {                              
  loc_id : int ;
  mutable succs : ('c * ('a, 'b, 'c) location) list ;
  mutable preds : ('c * ('a, 'b, 'c) location) list ;
  automaton : ('a, 'b, 'c) automaton ;
  mutable loc_attributes : 'b ;
}

如何使代码执行?

1个回答

7
好的,哈希表查找使用“= ”(结构相等)来确定键是否与您要查找的内容相同。结构相等需要深度检查所有子结构和其他内容。您有一个复杂的递归数据结构。也许在某个地方结构中存在循环,这会导致它无限循环。无论如何,考虑一下您想让哈希表如何告诉您键与您的相同,然后您需要使用该类型的相等性而不是默认的结构相等性;使用“Hashtbl.Make”函数器定义一个具有自定义相等性和/或哈希函数的哈希表模块。

没错,它可以工作。默认情况下,Hashtbl使用=来比较键,这是递归的。我创建了一个函数对象,用于使用==进行比较,该运算符不会递归比较。 - P Shved
1
是的,你可以使用 ==(物理相等); 但在这种情况下,请确保您传递的对象与最初用作键的对象相同(而不仅仅是具有相同结构的另一个对象)。 - newacct

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接