所以这是我破坏链表的代码。
void destroy(node *h){
if (h->next!=NULL){
destroy(h->next);
}
free(h);
h=NULL;
}
问题是打印仍会输出一堆数字:
11,2,15,3,9,//在毁灭之前
28495936,28495968,28496464,28496096,0,//摧毁后
不幸的是,由于分配原因,我无法更改void destroy(node *h)
参数。
我尝试过使用while循环方法,但我仍然得到相同的结果。我也试过向左移动并从末尾删除但后来我无法删除最后一个节点。
- 编辑--- 根据要求,这是打印功能
void print(node* N){
printf("%d, ", N->value);
if (N->next)
print_set(N->next);
if (N == NULL)
printf("Empty Set");
}
答案 0 :(得分: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;
答案 1 :(得分:2)
如果由于某些规则而无法通过 solution provided Albert,那么您作为作者的唯一可能性 必须记住列表的节点已被解除分配因此包含对内存的无效引用,并且由于后者而编写的代码可能无法取消引用此类指针,即它们可能无法传递给打印函数,因为这会通过访问un / deallocated内存来引发未定义的行为。
如果编写这样一些潜在的不安全代码,那么作为作者,您有责任谨慎使用它,并在您离开项目后为维护代码的其他程序员记录它。
答案 2 :(得分:1)
问题可能出在您尚未发布的代码中!
我假设你保留了一个指向列表的'head'指针,你的代码看起来像这样。
Node * myList;
.. do stuff..
destroy(myList);
print(myList);
问题是你没有在销毁之后设置myList = NULL
。
destroy(myList);
myList = NULL;
print(myList);
h=NULL
中的destroy()
无法执行任何操作,因为它正在修改本地参数。
答案 3 :(得分: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;
答案 4 :(得分:0)
我不知道你的结构是什么样的,但我猜是这样的:
struct {
int something;
int* value;
list* next;
}
问题是即使h
是NULL指针,h->value
和h->next
也不是。它们是NULL+1
和NULL+2
中的指针,可能指向内存中的随机位置。
答案 5 :(得分: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);
}