0

所以这是我销毁链表的代码。

void destroy(node *h){
    if (h->next!=NULL){
        destroy(h->next);
    }
    free(h);
    h=NULL;

}

问题是打印仍然输出一堆数字:

11, 2, 15, 3, 9, //销毁前

28495936, 28495968, 28496064, 28496096, 0, //销毁后

void destroy(node *h)不幸的是,由于分配原因,我无法更改参数。我尝试过使用 while 循环方法,但仍然得到相同的结果。我也尝试向左移动并从末尾删除,但我无法删除最后一个节点。

提前致谢。

--edit--- 根据要求,这里是打印功能

void print(node* N){
        printf("%d, ", N->value);
    if (N->next)
        print_set(N->next);
    if (N == NULL)
        printf("Empty Set");
}
4

6 回答 6

2

您必须设置h->next = NULL. 此外,在调用 之后,请destroy确保不再使用指针,因为它已被释放。所以,总是在之后destroy(n),确保你有n = NULL.

更好的方法可能是将签名更改为void destroy(node **h),因此代码变为:

void destroy(node **h){
    if ((*h)->next!=NULL){
        destroy(&h->next);
    }
    free(*h);
    *h=NULL;
}

然后,您确保以后不使用指针。

在您的print函数中,您必须在开头添加此检查:

if(N == NULL) return;
于 2013-10-21T08:37:12.277 回答
2

如果Albert提供的解决方案由于某些规则而无法实现,那么作为相关源代码的作者,您唯一的可能就是记住列表的节点已被释放,因此包含对内存的无效引用以及您编写的代码,因为后者可能不会取消引用此类指针,即它们可能不会传递给打印函数,因为这会通过访问未/释放的内存来引发未定义的行为。

如果编写此类潜在的不安全代码,作为作者,您有责任谨慎使用它并为您离开项目后维护代码的其他程序员提供很好的文档。

于 2013-10-21T08:57:32.863 回答
1

问题可能出在您尚未发布的代码中!

我假设您保留一个指向列表的“头”指针,并且您的代码如下所示。

Node * myList;

.. do stuff..

destroy(myList);
print(myList);

问题是你没有myList = NULL在销毁之后设置。

destroy(myList);
myList = NULL;
print(myList);

h=NULL的 indestroy()没有做任何事情,因为它正在修改本地参数。

于 2013-10-21T08:42:22.783 回答
1

这里的问题是h=null在你的函数中没有做任何事情。您正在修改本地参数,因此它不会在函数之外产生任何影响。

因此,您唯一要做的就是释放内存,但保持地址不变。您的列表仍然存在,指向随机内存位置(不是随机的:与以前相同,但此内存位置的值是随机的)

当您在那之后打印您的列表时(这很奇怪,因为您应该已经销毁它......为什么要再次打印它?),您会在内存中打印随机值。

这是一个问题,因为您的程序也可能崩溃(您正在访问未分配的内存)。

不幸的是,解决方案需要更改函数的签名:

void destroy(node **h){
    if ((*h)->next!=NULL){
        destroy((*h)->next);
    }
    free(*h);
    *h=NULL;

}

如果不能,则必须在销毁指针后将指针设置为 NULL,如下所示:

void destroy(node *h){
    if (h->next!=NULL){
        destroy(h->next);
        h->next=NULL;
    }
    free(h);
}

并在调用函数中:

destroy(myList);
myList=NULL;
于 2013-10-21T08:49:52.447 回答
0

我不知道你的结构是什么样的,但我猜是这样的:

struct {
  int something;
  int* value;
  list* next;
}

问题是,即使h是 NULL 指针,h->value也不h->next是。它们是 and 中的指针NULL+1NULL+2可能指向内存中的随机位置。

于 2013-10-21T08:38:03.560 回答
0

如果您正在处理单链表,请尝试此代码

void destroy(node *h){    
   node *n;    
   node *p; \\ variable to store previous term
   n=h;
   while(n->next!=NULL){
   p = n;
 }
  p->next=NULL;  
   free(n);

}

于 2013-10-21T08:50:01.887 回答