【问题标题】:Same code giving different results in Online IDE and local IDE相同的代码在在线 IDE 和本地 IDE 中给出不同的结果
【发布时间】:2017-06-30 10:58:43
【问题描述】:

以下程序用于从已排序的单链表中删除重复项。该代码在在线 IDE 中给出了垃圾值。但是当我评论这行时。

delete curr;

该程序在在线 IDE 本身中运行良好。这是我写的函数。代码的其他部分由在线法官明确定义(不是我)。

而且没有注释行 delete curr; 的代码在本地 IDE(代码块)中也可以正常工作。

完整计划:http://ideone.com/9bHab0

为什么我会得到垃圾值?

Node *removeDuplicates(Node *root)
{
 // your code goes here
    struct Node* curr = root,*prev = NULL;
    while(curr)
    {
        if(prev==NULL)
            prev = curr;
        else if(curr->data!=prev->data)
            prev = curr;
        else
        {
            prev->next = curr->next;
            delete curr;
            curr = prev->next;
        }
    }
    return root;
}

编辑: 可以看到位置被删除的指针立即重新分配。因此这里不可能有一个悬空指针!

【问题讨论】:

  • 你试过在调试器下运行它吗?
  • new分配你的Node实例? 全部?他们的析构函数在做什么?
  • 这是 C (struct Node* curr) 和 C++ (delete curr) 代码的完美结合。你确定调用者是C++,调用operator new分配实例?
  • 一旦它必须通过 else if 块就会进入无限循环 - 你确定这是你的实际代码
  • @TomTanner:我不看场外资源。关于 SO 的问题应该是独立的。这在有关如何生成 minimal reproducible example 的说明中进行了说明。

标签: c++ pointers linked-list garbage


【解决方案1】:

让我们举一个非常简单的例子,有一个两节点列表,例如

node1 -> node2

在第一次迭代中,prevNULL,所以你可以使用 prev = curr。现在currprev 指向同一个节点。

这意味着在第二次迭代中 if 条件都为假(prev != NULLcurr->data == prev->data)你进入 else 部分,你有

prev->next = curr->next;
delete curr;
curr = prev->next;

你在这里delete curr 但是 curr 指向与prev 相同的内存,导致未定义的行为赋值curr = prev->next,因为您现在取消引用流浪指针prev

更糟糕的是,然后您进入 第三次 迭代,其中 prev 仍然指向已删除的第一个节点,并再次取消引用无效的 prev 指针(在您的第二个 if条件)并且您再次进入 else 部分,您将继续进行无效的取消引用。以此类推无限(或者你会崩溃)。

【讨论】:

  • 而解决方法是:将前两个条件分支中的prev = curr;替换为prev = curr; curr = curr->next;
  • curr = curr->next 添加到 if 部分和 else if 部分 解决了问题。感谢您的解决方案。我是否应该更改问题的标题以避免对这个问题产生不必要的关注?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-06-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-09-26
  • 2018-07-15
相关资源
最近更新 更多