我的哈希表 C++ 中的内存泄漏

memory leak in my hashtable c++

本文关键字:内存 泄漏 哈希表 C++ 我的      更新时间:2023-10-16

我创建了一个哈希表类并以这种方式编写了它的析构函数

HashMap::~HashMap()
{
    for (int i=0; i<cap; i++)
    {
        Node* ptr = Hashtable[i];
        while (ptr)
        {
            Node* delptr;
            delptr=ptr;
            ptr=ptr->next;
            delete delptr;
        }
    }
    delete [] Hashtable;
}

既然它有一个析构函数,为什么它保持泄漏内存?

这是我实现构造函数的方式

HashMap::HashMap()
{
    Hashtable= new Node* [INITIAL_BUCKET_COUNT];
    sz=0;
    cap=INITIAL_BUCKET_COUNT;
    hashfunction=defaulthashfunction;
}

additem 函数是:

void HashMap::add(const std::string& key, const std::string& value)
{
    int index = hashfunction(key)%cap;;
    Node* ptr=Hashtable[index];
    Node* newnode=new Node;
    if (contains(key)==false)
    {
        if (ptr == nullptr)
        {
            newnode->key=key;
            newnode->value=value;
            newnode->next=NULL;
            Hashtable[index]=newnode;
        }
        else
        {
            newnode->key=key;
            newnode->value=value;
            newnode->next=NULL;
            while(ptr->next != NULL)
            {
                ptr = ptr->next;
            }
            ptr->next=newnode;
         }}
    if (loadFactor() > 0.8)
    {
        int newcap = cap*2+1;
        Node** newhash = new Node* [newcap];
        rehash(newhash, Hashtable, cap, newcap);
        for (int i=0; i <cap; i++)
        {
            Node* ptr=Hashtable[i];
            while (ptr)
            {
                Node* delptr;
                delptr=ptr;
                ptr=ptr->next;
                delete delptr;
            }
        }
        delete [] Hashtable;
        Hashtable=newhash;
    }
}

这是我的重新哈希函数,唯一的错误始终是这一行:节点* nnode = 新节点;如果我把这段代码放在循环的一侧,错误就会变成 20,它表明问题出在我的析构函数中。但是在调整我的哈希表大小之前,它没有错误,我测试了几次。为什么 rehash 函数会保留泄漏内存?

void HashMap::rehash(Node** newhash, Node** oldhash, int oldcap, int newcap)
{
    for (int x=0; x<newcap; x++)
    {
        newhash[x]=NULL;
    }
    //Node* nnode = new Node;
    for (int i = 0; i<oldcap; i++)
    {
        Node* ptr=oldhash[i];
        while (ptr!=NULL)
        {
            int index = hashfunction(ptr->key)%newcap;
            Node* nptr=newhash[index];
            Node* nnode = new Node;
            if (nptr==NULL)
            {
                nnode->key=ptr->key;
                nnode->value=ptr->value;
                nnode->next=NULL;
                newhash[index]=nnode;
            }
            else
            {
                while (nptr->next != NULL)
                {
                    nptr=nptr->next;
                }
                nnode->key=ptr->key;
                nnode->value=ptr->value;
                nnode->next=NULL;
                nptr->next=nnode;
                }
            ptr=ptr->next;
         }
    }
}

--插入--

Valgrind 输出中的任何内容都表明内存泄漏。

==6949== LEAK SUMMARY:
==6949==    definitely lost: 0 bytes in 0 blocks
==6949==    indirectly lost: 0 bytes in 0 blocks

但是,Valgrind 告诉您您没有初始化某些数据:

==6949== Conditional jump or move depends on uninitialised value(s)
==6949==  Uninitialised value was created by a heap allocation
==6949==    at 0x402B774: operator new[](unsigned int) (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==6949==    by 0x804A75C: HashMap::HashMap() (HashMap.cpp:31)
==6949== Conditional jump or move depends on uninitialised value(s)
==6949==    at 0x402B774: operator new[](unsigned int) (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==6949==    by 0x804A75C: HashMap::HashMap() (HashMap.cpp:31)
==6949== Use of uninitialised value of size 4

具体来说,你的构造函数HashMap::HashMap() (HashMap.cpp:31),问题就在那里,而不是你的析构函数。

最后,代码由于空指针访问而崩溃。

==6949== Invalid read of size 4
==6949==    at 0x40EAD76: std::string::assign(std::string const&) (in /usr/lib/i386-linux-gnu/libstdc++.so.6.0.18)
==6949==    by 0x804A51A: main (main.cpp:16)
==6949==  Address 0x0 is not stack'd, malloc'd or (recently) free'd

您应该查看main.cpp的第16行,看看它在做什么,但是在修复这些未初始化的值之前,所有赌注都是关闭的。