【问题标题】:How to know if a linked list is correctly deleted?如何知道链表是​​否被正确删除?
【发布时间】:2014-06-24 03:13:15
【问题描述】:

我得到了以下算法,但我不太确定函数 erase 是否是在 C 中删除整个列表的正确方法,因为我不确定我是否正确释放了列表中的每个节点。

#include <stdio.h>
#include <stdlib.h>

struct lis
{ int n;
struct lis *next;
};

typedef struct lis *list;

void create (list *l)
{
    *l=NULL;    
}

int read (void)
{
    int num;
    puts("ENTER A NUMBER");
    scanf ("%d",&num);
    return num;
}

void add (int n, list *l)
{
    list new,previous,current;
    new=malloc (sizeof(list));
    (*new).n=n;
    (*new).next=NULL;
    if (*l==NULL)
    {
        *l=new;
    }
    else
    {
        previous=*l;
        current=*l;
        while ((current!=NULL) && ((*current).n<(*new).n))
        {
            previous=current;
            current=(*current).next;
        }
        if (previous==current)
        {
            (*new).next=*l;
            *l=new;
        }
        else
        {
            (*previous).next=new;
            (*new).next=current;
        }
    }
}

void insert (list *l)
{
int n;
n=read();
while (n!=0)
{
    add(n, &(*l));
    n=read();
    }
}

void print (list l)
{
    if (l!=NULL)
    {
        while (l!=NULL)
        {
         printf ("%d\n",(*l).n);
            l=(*l).next;
        }
    }
    else
{
        puts ("empty list");
    }
}

int isempty (list l)
{
    return (l==NULL);
}



void erase (list *l)
{
    list next;
    list current=*l;
    while (current!=NULL)
    {
        next=(*current).next;
        free (current);
        current=next;                
    }
    *l=NULL;
}



int main ()
{  
    list l;
    create (&l);
    insert (&l);
    isempty(l)?puts("empty list"):puts("no empty list");
    print (l);
    erase (&l);
    isempty(l)?puts("empty list"):puts("no empty list"); //obviously this return true but just check the header node
return 0;
}

尝试使用 gdb,但我什至不知道如何从非主函数的函数中跟踪代码,也不知道如何检查堆中分配的变量是否空闲。 因此,任何为我指明使用 gdb 的正确方向或告诉我代码是否正常的答案都将不胜感激。

【问题讨论】:

  • 使用 Valgrind 是处理这类事情的最佳选择。
  • 稍微相关:我在这里不只是挑剔;将typedef-ed 指针类型扔掉。它只为您的代码提供了晦涩难懂的内容,并且在您的学习曲线的这一点上,您希望查看和管理这些星号。严重地。不是开玩笑。
  • 我会看看 Valgrind,并且会尝试在没有 typedef 的情况下实现它,谢谢!

标签: c linked-list free


【解决方案1】:

您的erase() 是正确的,但您可能会丢失其中一个指针并执行以下操作:

void erase (list *l)
{
    while (*l)
    {
        list victim = *l;
        *l = victim->next;
        free (victim);
    }
}

假设您正确插入代码并且总是以 NULL 终止您的列表,这就足够了。哦,您的添加功能可能会显着减少:

void add (int n, list *l)
{
    list p = NULL;

    while (*l && (*l)->n < n)
        l = &(*l)->next;

    p = malloc(sizeof(*p))
    p->n = n;
    p->next = *l;
    *l = p;
}

我将错误检查留给您来实施,但您的问题的直接答案是,是的,如果首先正确构建,您的 erase 方法将正确清除列表。

PS:这个:add(n, &amp;(*l));insert 函数中可以是add(n, l);

【讨论】:

  • 很好的答案,感谢您提供的额外信息,我将尝试插入功能的简化版本。
猜你喜欢
  • 2012-02-17
  • 1970-01-01
  • 2019-07-15
  • 1970-01-01
  • 1970-01-01
  • 2021-12-01
  • 2020-03-31
  • 2011-03-21
  • 1970-01-01
相关资源
最近更新 更多