C++线性探测哈希表指针分配引发Search函数段错误求助
段错误核心原因
你在HashTable构造函数中重新定义了同名的局部变量HashNode **table,后续初始化节点操作的都是栈上的局部table,类的私有成员table始终未被赋值,是野指针。你之前构造函数里的cout输出验证的是局部变量table的节点状态,误以为成员变量初始化成功,实际上成员table一直指向非法地址,Search函数访问时直接触发段错误。
修复方法:把构造函数中HashNode **table = new (HashNode*)[TableSlots] ;前面的HashNode **去掉,直接给类成员变量赋值即可:
HashTable(){ size = 0 ; // 直接操作类成员table,不要重新定义局部变量 table = new HashNode*[TableSlots] ; for (int i = 0; i < TableSlots; i++){ table[i] = new HashNode("NULL", "never used") ; cout << "hash node status: " << table[i]->status << endl ; cout << "hash node word: " << table[i]->word << endl ; } tombstone = new HashNode("NULL","tombstone") ; cout << "created hash table" << endl ; }
其他需要修复的问题
- Search函数中
cout << "table size:" << table.size() << endl;是错误写法,table是指针不是容器,没有size()方法,直接删除该行即可,否则编译无法通过。 - 你未实现
SearchSlot成员函数,deleteNode调用时会触发链接错误,需要补充实现:int HashTable::SearchSlot(string word) { int slot = hashFunction(word); while (table[slot]->status != "never used"){ if(table[slot]->word == word && table[slot]->status == "occupied") return slot; slot++ ; slot %= TableSlots ; } return -1; // 未找到返回-1 } - 哈希函数冗余度过高,26个if判断可以简化为一行代码,同时要增加异常分支避免未初始化变量越界:
int HashTable::hashFunction(string word){ if(word.empty()) return 0; char lastChar = tolower(word.back()); if(lastChar < 'a' || lastChar > 'z') return 0; return (lastChar - 'a') % TableSlots; } - 类未实现析构函数,会产生严重内存泄漏,补充析构函数:
~HashTable(){ for(int i=0; i<TableSlots; i++){ // 不要删除全局共享的tombstone节点 if(table[i] != tombstone) delete table[i]; } delete[] table; delete tombstone; } - 当前哈希表大小固定为26,插入超过26个元素时会进入死循环,需要在Insert函数开头增加容量判断:
if(size >= TableSlots) return; - 多个HashTable实例共享同一个tombstone节点会触发double free问题,要么每个实例单独维护tombstone,要么析构时跳过对tombstone的释放。
内容的提问来源于stack exchange,提问作者melarnmurphy
相关产品推荐
相关产品推荐

