在简单的哈希表中解决内存泄漏和语法问题

Solving leaky memory and syntax issues in a simple hash table

本文关键字:泄漏 语法 问题 内存 解决 简单 哈希表      更新时间:2023-10-16

我正在实现一个基本的哈希表。我对表格的逻辑是有道理的(至少对我来说),但我对我的C++有点生疏。我的程序在运行时返回空闲内存错误,但我似乎无法弄清楚我的问题在哪里。我认为这与我在各种类函数中调用指针的方式有关。

#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()] = '';
    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;
}

问题是,当您调用 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;
}
for(h=0;*v!=0;v++,a=a*b%(49-1))
    h = (a*h + *v)%50;
delete[] v;                             //Delete the char* to prevent leaky 

您正在递增 v,然后删除无效的内存位置。