我创建了一个哈希表类,并以这种方式编写了它的析构函数
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;
}
}
这是我的rehash函数,唯一的错误总是这一行:Node * nnode = new Node; 如果我把这个代码放在循环的一边,错误就变成了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;
}
}
}
- 插入 -
答案 0 :(得分:0)
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行,看看它在做什么,但在您修复这些未初始化的值之前,所有的赌注都会关闭。