2009-09-08 31 views
3

來自外部源的非常巨大的ocaml程序需要修復。其中一個問題是程序在看似無辜的線路上崩潰: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 ; 
} 

應該做些什麼來使代碼執行?

回答

6

好吧,哈希表查找使用「=」(結構相等)來確定一個關鍵字是否與您正在查找的相同。結構平等需要深入檢查所有子結構和東西。你有一個複雜的遞歸數據結構。也許在某個時候結構中有一個循環,這會導致它無限循環。在任何情況下,都要考慮如何讓散列表告訴您鍵是否與您的相同,然後您需要使用這種相等性而不是默認的結構相等性;使用函數來定義具有自定義相等和/或散列函數的散列表模塊。

+0

是的,它的工作原理。默認情況下,Hashtbl使用'='來比較遞歸的鍵。我做了一個使用'=='的函數來達到這個目的,這個運算符沒有遞歸比較。 – 2009-09-09 11:50:16

+1

是的,你可以使用==(物理相等);但在這種情況下,請確保傳入的對象與最初用作關鍵字的對象相同(而不僅僅是具有相同結構的另一個對象) – newacct 2009-09-10 04:37:36