我编写了一个代码,用于从单链表中删除节点a。我测试了这段代码,输出很好。我对上次"其他"有点困惑在此代码中阻止。这是对的吗? 我的意思是,在释放(p-> ptr)节点之后,我仍然可以访问它旁边的节点吗?
NODE* delNODE(NODE *HEAD,int position){
int k=1;
NODE *p;
if(HEAD==NULL){
printf("List Empty\n");
return HEAD;
}
p=HEAD;
if(position==1){
p=HEAD;
HEAD=HEAD->ptr;
free(p);
printf("Success!\n");
return HEAD;
}
else{
while(k<position-1){
k++;
p=p->ptr;
}
if((p->ptr)==NULL)
{
printf("NO such position\n");
}
else{
free(p->ptr);
p->ptr=p->ptr->ptr;
printf("Success!\n");
}
}
return HEAD;
}
答案 0 :(得分:1)
不,这不行。这似乎“工作”的唯一原因是因为在你尝试过的那些时候,内存分配器已经标记了你已经释放的内存,但实际上并没有覆盖它或以其他方式触及它,所以之前价值仍然坐在那个记忆地址。你不能指望这永远是真的。例如,如果该节点是特定页面中最后分配的内存块,那么就没有什么可以阻止free()
的实现从进程的虚拟内存表中删除它,从而导致下次尝试访问时出现分段违例它。
改为使用临时变量:
NODE * tempnode = p->ptr->ptr;
free(p->ptr);
p->ptr = tempnode;
答案 1 :(得分:0)
你不能,也不应该。使用中间变量,就像删除头节点的第二个if语句一样。