【问题标题】:My linked-list node removing function causes other parts of my program to crash我的链表节点删除功能导致我的程序的其他部分崩溃
【发布时间】:2012-07-20 00:41:08
【问题描述】:

我在一些作业中遇到了一个奇怪的错误,它让我用链表制作了一个堆栈。我的程序中的所有功能都可以完美运行,即使在我没有节点的一开始,或者在删除一些节点之后也是如此。但是当我创建节点并将它们全部删除以便我回到零时,每个函数都会导致崩溃。我已经尝试研究这个问题,但我发现的解决方案看起来与我已经得到的几乎相同,所以很明显我没有看到一些关键的东西。

这是节点删除功能(我怀疑是这一切的罪魁祸首)

void remove(node** root)
{   
    node* temp = *root;
    node* previous = 0;
    if(*root)
    {
        while((*root)->next)
        {
            previous = *root;
            *root = (*root)->next;
        }
        delete *root;
        *root = temp;
        if(previous)
        {
            previous->next = 0;
        }
    }
    else
    {
        std::cout<<"cannot delete items from empty list\n";
    }
}

这是节点插入函数

void insert(node** root)
{
    node* temp = *root;
    if(*root)
    {
        while((*root)->next)
        {
            (*root) = (*root)->next;
        }
        (*root)->next = new node;
        (*root)->next->data = getnum();
        (*root)->next->next = 0;
        *root = temp;
    }
    else
    {
        (*root) = new node;
        (*root)->data = getnum();
        (*root)->next = 0;
    }

}

我很确定问题出在我链接的代码中,但以防万一,这是完整作业的 pastebin http://pastebin.com/AWtG4qjD

【问题讨论】:

  • 我看不出有什么问题。当你在 valgrind 下运行它时它会做什么?风格问题:不要使用 *root 作为迭代变量,这会造成混淆。特别是当您需要在迭代后将其重置为原始值时不要这样做。并且尤其是不要将该原始值称为“temp”(这不是临时的任何东西,而是正在修改的实际列表!)。另外:你为什么要迭代到最后插入或删除?为什么不按相反的顺序存储列表,并在恒定时间内直接对头部进行操作?
  • 这是作业的一部分。您的建议听起来确实是一种更好的做事方式,但由于这是我的第一个链表作业,我怀疑我被要求以一种故意复杂的方式来帮助我更好地学习它。我实际上是一个相当新的程序员,所以我还没有真正弄清楚如何编写干净整洁的代码,因此非常感谢样式建议。同样,我实际上并不知道 valgrind 是什么,但我正在谷歌上搜索它,它看起来很有趣

标签: c++ linked-list stack


【解决方案1】:

remove 实现不正确。假设列表有一个元素。 在这种情况下,执行 delete *root; 后 temp 将指向“不存在的内存” 但是你正在做的是*root = temp; 这样你会导致 root 指向无效节点。 这会导致后来的奇怪行为 使您的实现正确的可能方法是:

void remove(node** root)
{
    //TODO: your code here
    node* temp = *root;
    node* previous = 0;
    if(*root)
    {
        while((*root)->next)
        {
            previous = *root;
            *root = (*root)->next;
        }
        delete *root;
        if(previous)
        {
            *root = temp;
            previous->next = 0;
        }
        else {
            *root = NULL;
        }
    }
    else
    {
        std::cout<<"cannot delete items from empty list\n";
    }
}

但我不建议您使用根指针迭代列表。定义一些迭代器并用它查找结尾而不是更改 *root

【讨论】:

  • 这似乎是问题所在,非常感谢您的提示!
猜你喜欢
  • 2019-05-23
  • 2011-12-08
  • 1970-01-01
  • 2018-10-17
  • 1970-01-01
  • 2022-01-15
  • 1970-01-01
  • 2017-04-12
  • 1970-01-01
相关资源
最近更新 更多