当我通过删除临时节点来释放内存时,我遇到了读取访问冲突。但只有当我返回虚假陈述时

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 那些newdelete 语句在这段代码中实际上是完全没有必要的,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】:

newdelete 在那里毫无用处。 当您声明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 = falsereturn true; 而不是 return equal; @Artemy,是的,你是对的,尽管有些人更喜欢在他们的函数中只有一个 return 语句(这是另一场争论)。但我的回答只是关于访问冲突问题。

以上是关于当我通过删除临时节点来释放内存时,我遇到了读取访问冲突。但只有当我返回虚假陈述时的主要内容,如果未能解决你的问题,请参考以下文章

Cupy 释放统一内存

WPF WebBrowser Memory Leak 问题及临时解决方法

iOS 7 Sprite Kit 释放内存

对删除分配给结构数组的动态内存感到困惑

C++链表删除节点

list在erase之后就释放内存,vector也可以通过swap操作来删除,请问dequeue如何释放已删除元素的内存?