当我通过删除临时节点来释放内存时,我遇到了读取访问冲突。但只有当我返回虚假陈述时
Posted
技术标签:
【中文标题】当我通过删除临时节点来释放内存时,我遇到了读取访问冲突。但只有当我返回虚假陈述时【英文标题】:When I free up memory by deleting a temporary node, I get a read access violation. But only when I return a false statement 【发布时间】:2017-09-29 06:34:39 【问题描述】:我创建了一个实现双向链表并重载比较的类 操作员。我制作了一个临时节点来循环浏览链接列表并在完成后将其删除。每当我返回虚假陈述时,我都会遇到读取访问冲突。 我已经坚持了几个小时。任何帮助都会很棒。
bool operator== (const dlist& a, const dlist& b)
if (a.size() != b.size())
return false;
bool equal = true;
int index = 0;
dlist::node* temp = new dlist::node;
temp = a.head();
dlist::node* temp1 = new dlist::node;
temp1 = b.head();
while (index < a.size())
if (temp->value == temp1->value)
index++;
else
equal = false;
break;
temp = temp->next;
temp1 = temp1->next;
delete temp, temp1;
return equal;
【问题讨论】:
能否提供定义dlist
的代码?
提示:你创建的两个对象会发生什么?你到底要删除什么?
当你在dlist::node* temp = new dlist::node
后面紧跟temp = a.head()
时,它与例如相同。 int a = 10; a = 5;
然后想知道为什么 a
不等于 10
。
那些new
和delete
语句在这段代码中实际上是完全没有必要的,new
只是造成内存泄漏(因为你在之后重定向指针)和delete
是试图释放他们没有分配的内存
delete temp, temp1;
释放由temp
指向的内存,而不是temp1
。您需要使用delete temp; delete temp1;
。
【参考方案1】:
在这部分代码中
dlist::node* temp = new dlist::node;
temp = a.head();
dlist::node* temp1 = new dlist::node;
temp1 = b.head();
您创建并立即泄漏两个对象。
new
的两行都不需要。
如果您删除它们,您就不会再泄漏,否则您将拥有相同的功能。
然后很明显,这种删除临时工的尝试
delete temp, temp1;
是不需要的,因为它们都是本地指针,但不指向任何本地实例化的东西。它们只是指向列表中不可删除的元素。 (而且考虑到逗号运算符的工作方式,我认为这种删除两个指针的方式是行不通的。)
【讨论】:
你的意思是内存入侵? @A.Godnov 对不起,我不明白你的意思。 “内存入侵”是什么意思?我的搜索引擎对此有很多 Startrek 参考,但不知何故,我相信这不是您所指的。【参考方案2】:new
和 delete
在那里毫无用处。
当您声明dlist::node* temp
时,您声明了一个可以保存地址位置的变量。
您可以为其分配内存中现有区域的地址或分配新的内存块。
在第二种情况下,你必须记住在使用后删除分配的块。
在您的函数中,您正在分配内存,将此内存的地址分配给一个变量 (dlist::node* temp
),并且在您将临时指向另一个地址 (temp = a.head()
) 后立即导致内存泄漏(分配的内存不再被任何变量寻址)。
temp1
变量出现同样的错误。
你的代码应该是这样的:
bool operator== (const dlist& a, const dlist& b)
if (a.size() != b.size())
return false;
bool equal = true;
int index = 0;
dlist::node* temp = temp = a.head();
dlist::node* temp1 = temp1 = b.head();
while (index < a.size())
if (temp->value == temp1->value)
index++;
else
equal = false;
break;
temp = temp->next;
temp1 = temp1->next;
return equal;
【讨论】:
你不需要 equal - 只需return false
而不是 equal = false
和 return true;
而不是 return equal;
@Artemy,是的,你是对的,尽管有些人更喜欢在他们的函数中只有一个 return 语句(这是另一场争论)。但我的回答只是关于访问冲突问题。以上是关于当我通过删除临时节点来释放内存时,我遇到了读取访问冲突。但只有当我返回虚假陈述时的主要内容,如果未能解决你的问题,请参考以下文章
WPF WebBrowser Memory Leak 问题及临时解决方法
list在erase之后就释放内存,vector也可以通过swap操作来删除,请问dequeue如何释放已删除元素的内存?