当我尝试从包含一百万首歌曲的文件中制作和散列对象时,在大约12000次成功哈希后,我得到一个奇怪的分段错误。
任何人都知道为什么:
Segmentation fault: 11
运行程序时会发生吗?
我有这些类用于散列对象:
class Node():
def __init__(self, key, value = None):
self.key = key
self.value = value
def __str__(self):
return str(self.key) + " : " + str(self.value)
class Hashtable():
def __init__(self, hashsize, hashlist = [None]):
self.hashsize = hashsize*2
self.hashlist = hashlist*(self.hashsize)
def __str__(self):
return self.hashlist
def hash_num(self, name):
result = 0
name_list = list(name)
for letter in name_list:
result = (result*self.hashsize + ord(letter))%self.hashsize
return result
def check(self, num):
if self.hashlist[num] != None:
num = (num + 11**2)%self.hashsize#Kolla här jättemycket!
chk_num = self.check(num)#här med
return chk_num#lär dig
else:
return num
def check_atom(self, num, name):
if self.hashlist[num].key == name:
return num
else:
num = (num + 11**2)%self.hashsize
chk_num = self.check_atom(num, name)#läs här
return chk_num#läs det här
def put(self, name, new_atom):
node = Node(name)
node.value = new_atom
num = self.hash_num(name)
chk_num = self.check(num)
print(chk_num)
self.hashlist[chk_num] = node
def get(self, name):
num = self.hash_num(name)
chk_num = self.check_atom(num, name)
atom = self.hashlist[chk_num]
return atom.value
我在这段代码中调用了函数:
from time import *
from hashlist import *
import sys
sys.setrecursionlimit(1000000000)
def lasfil(filnamn, h):
with open(filnamn, "r", encoding="utf-8") as fil:
for rad in fil:
data = rad.split("<SEP>")
artist = data[2].strip()
song = data[3].strip()
h.put(artist, song)
def hitta(artist, h):
try:
start = time()
print(h.get(artist))
stop = time()
tidhash = stop - start
return tidhash
except AttributeError:
pass
h = Hashtable(1000000)
lasfil("write.txt", h)
答案 0 :(得分:4)
您遇到分段错误的原因是这一行:
sys.setrecursionlimit(1000000000)
我认为您添加了它是因为您收到了RuntimeError: maximum recursion depth exceeded
。提高递归限制不会为调用堆栈分配更多内存,它只是推迟上述异常。如果设置得太高,解释器就会耗尽堆栈空间并访问不属于它的内存,从而导致随机错误(可能是段错误,但理论上一切皆有可能)。
真正的解决方案是不使用无界递归。对于像平衡搜索树这样的东西,递归深度限制在几十个级别,没关系,但你不能用递归替换长循环。
此外,除非这是创建哈希表的练习,否则您应该只使用内置的dict
。如果它是创建哈希表的练习,请考虑这一点,提示您的哈希表有些糟糕:它表示探测长度至少为1000,更可能几个千。它最多只应该是几十个,理想情况下是一位数。