C++ 在简单哈希表中解决内存泄漏和语法问题
我正在实现一个基本的哈希表。这个表的逻辑(至少对我来说)是有道理的,但是我的C++有点生疏了。我的程序在运行时返回一个可用内存错误,但我似乎无法找出问题所在。我认为这与我如何调用各种类函数中的指针有关C++ 在简单哈希表中解决内存泄漏和语法问题,c++,hashtable,C++,Hashtable,我正在实现一个基本的哈希表。这个表的逻辑(至少对我来说)是有道理的,但是我的C++有点生疏了。我的程序在运行时返回一个可用内存错误,但我似乎无法找出问题所在。我认为这与我如何调用各种类函数中的指针有关 #include <iostream> #include <unordered_map> #include <string> #include <cmath> #include <exception> using namespace st
#include <iostream>
#include <unordered_map>
#include <string>
#include <cmath>
#include <exception>
using namespace std;
int hashU(string in/*, int M*/){ //hThe hash function that utilizes a smal pseusorandom number
char *v = new char[in.size() + 1]; //generator to return an number between 0 and 50. (I arbitrarily chose 50 as the upper limit)
copy(in.begin(), in.end(), v); //First the input string is turned into a char* for use in the the function.
v[in.size()] = '\0';
int h, a = 31415, b = 27183;
for(h=0;*v!=0;v++,a=a*b%(49-1))
h = (a*h + *v)%50;
delete[] v; //Delete the char* to prevent leaky memory.
return (h<0) ? (h+50) : h; //Return number
}
struct hashNode{ //The node that will store the key and the values
string key;
float val;
struct hashNode *next;
};
struct hashLink{ //The linked list that will store additional keys and values should there be a collision.
public:
struct hashNode *start; //Start pointer
struct hashNode *tail; //Tail pointer
hashLink(){ //hashLink constructor
start=NULL;
tail=NULL;
}
void push(string key, float val); //Function to push values to stack. Used if there is a collision.
};
void hashLink::push(string key, float val){
struct hashNode *ptr;
ptr = new hashNode;
ptr->key = key;
ptr->val = val;
ptr->next = NULL;
if(start != NULL){
ptr->next = tail;
}
tail = ptr;
return;
}
struct hashTable{ //The "hash table." Creates an array of Linked Lists that are indexed by the values returned by the hash function.
public:
hashLink hash[50];
hashTable(){ //Constructor
}
void emplace(string in, float val); //Function to insert a new key and value into the table.
float fetch(string in); //Function to retrieve a stored key.
};
void hashTable::emplace(string in, float val){
int i = hashU(in); //Retrieve index of key from hash function.
hashNode *trav; //Create node traveler
trav = hash[i].start; //Set the traveler to the start of the desired linked list
while(trav!=hash[i].tail){ //Traverse the list searching to see if the input key already exists
if(trav->key.compare(in)==0){ //If the input key already exists, its associated value is updated, and the function returns.
trav->val = val;
return;
}
else //Travler moves to next node if the input key in not found.
trav = trav->next;
}
hash[i].push(in,val); //If the traveler does not see the input key, the request key must not exist and must be created by pushing the input key and associated value to the stack.
return;
}
float hashTable::fetch(string in){
int i = hashU(in); //Retrieve index of key
hashNode *trav; //Create node traveler and set it to the start of the appropriate list.
trav = hash[i].start;
while(trav!=hash[i].tail){ //Traverse the linked list searching for the requested key.
if(trav->key.compare(in)==0){ //If the the requested key is found, return the associated value.
return trav->val;
}
else
trav = trav->next; //If not found in the current node, move to the next.
}
return false; //If the requested key is not found, return false.
}
int main(){
hashTable vars; //initialize the hash table
float num = 5.23; //create test variable
vars.emplace("KILO",num);
cout<<vars.fetch("KILO")<<endl;
return 0;
}
#包括
#包括
#包括
#包括
#包括
使用名称空间std;
int hashU(字符串in/*,int M*/){//h使用一个小伪随机数的哈希函数
char*v=new char[in.size()+1];//生成器返回一个介于0和50之间的数字。(我任意选择50作为上限)
copy(in.begin(),in.end(),v);//首先将输入字符串转换为char*,以便在函数中使用。
v[in.size()]='\0';
int h,a=31415,b=27183;
对于(h=0;*v!=0;v++,a=a*b%(49-1))
h=(a*h+*v)%50;
delete[]v;//删除字符*以防止内存泄漏。
返回(hkey=键;
ptr->val=val;
ptr->next=NULL;
如果(开始!=NULL){
ptr->next=尾部;
}
tail=ptr;
返回;
}
struct hashTable{//“hash table.”创建一个链表数组,链表由hash函数返回的值索引。
公众:
hashLink散列[50];
hashTable(){//构造函数
}
void emplace(string in,float val);//函数将新键和值插入表中。
float fetch(字符串输入);//用于检索存储密钥的函数。
};
void hashTable::emplace(字符串输入,浮点值){
int i=hashU(in);//从哈希函数中检索键的索引。
hashNode*trav;//创建节点旅行者
trav=hash[i].start;//将traveler设置为所需链表的开头
while(trav!=hash[i].tail){//遍历列表搜索以查看输入键是否已经存在
如果(trav->key.compare(in)==0){//如果输入键已经存在,则更新其关联值,函数返回。
trav->val=val;
返回;
}
else//Travler在未找到输入键的情况下移动到下一个节点。
trav=trav->next;
}
hash[i].push(in,val);//如果旅行者没有看到输入键,则请求键必须不存在,并且必须通过将输入键和关联值推送到堆栈中来创建。
返回;
}
浮点哈希表::获取(字符串位于){
int i=hashU(in);//检索键的索引
hashNode*trav;//创建节点旅行者,并将其设置为相应列表的开头。
trav=hash[i]。开始;
而(trav!=hash[i].tail){//遍历链表搜索请求的键。
如果(trav->key.compare(in)==0){//如果找到请求的键,则返回关联的值。
返回trav->val;
}
其他的
trav=trav->next;//如果在当前节点中找不到,则移动到下一个节点。
}
return false;//如果找不到请求的密钥,则返回false。
}
int main(){
hashTable vars;//初始化哈希表
float num=5.23;//创建测试变量
变量安放(“千”,数量);
库特
您正在递增v,然后删除无效的内存位置
您正在递增v,然后删除一个无效的内存位置。问题是,当您调用delete[]v
时,您已经升级了v
,因此它指向字符串末尾的0
,这是要删除的错误地址
此外,您还浪费了大量代码,不必要地将字符串从已经作为c字符串可用的位置复制出去
unsigned int hashU(string in/*, int M*/) {
const char* v = in.c_str();
unsigned int h, a = 31415, b = 27183;
for(h=0;*v!=0;v++,a=a*b%(49-1))
h = (a*h + *v);
return h % 50;
}
问题是,当您调用delete[]v
时,您已经升级了v
,因此它指向字符串末尾的0
,这是要删除的错误地址
此外,您还浪费了大量代码,不必要地将字符串从已经作为c字符串可用的位置复制出去
unsigned int hashU(string in/*, int M*/) {
const char* v = in.c_str();
unsigned int h, a = 31415, b = 27183;
for(h=0;*v!=0;v++,a=a*b%(49-1))
h = (a*h + *v);
return h % 50;
}
为什么不调用“in.c_str()”将“in”转换为字符串?这样可以节省分配内存的时间。在hashU
中,这是一段很短的代码,我可以找到2个不必要的复制,1个不安全的指针(有很多不合逻辑的操作),1为
语句隐写。内存泄漏只是一个结果;真正的问题是代码质量。为什么不调用“in.c_str()”将“in”转换为字符串?这样可以节省分配内存的时间。在hashU
这段如此短的代码中,我可以找到2个不必要的复制,1个不安全的指针(有很多不合逻辑的操作),1对for
语句的编写不清楚。内存泄漏只是一个结果;真正的问题是代码质量。这就是问题所在。谢谢!这就是问题所在。谢谢!