【问题标题】:Is this code to delete a node from linked list correct?这段代码从链表中删除节点是否正确?
【发布时间】:2014-10-16 11:32:12
【问题描述】:

我编写了一个代码来从单链表中删除一个节点 a。我已经测试了这段代码,输出很好。我对这段代码中的最后一个“else”块有点困惑。这是正确的吗? 我的意思是,在释放 (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;
}

【问题讨论】:

  • @pala 这样做也是不正确的。

标签: c singly-linked-list


【解决方案1】:

不,这不行。这似乎“工作”的唯一原因是因为在您尝试过它的那些时候,内存分配器已将您释放的内存标记为可用,但实际上并没有覆盖它或以其他方式触及它,所以前面value 仍然在那个内存地址处。你不能指望这总是正确的。例如,如果该节点是特定页面中最后分配的一块内存,则没有什么可以阻止您的free() 实现从进程的虚拟内存表中删除它,从而导致您下次尝试访问它时出现分段违规。

改用临时变量:

NODE * tempnode = p->ptr->ptr;
free(p->ptr);
p->ptr = tempnode;

【讨论】:

    【解决方案2】:

    你不能,也不应该。使用中间变量,就像在删除头节点的第二个 if 语句中一样。

    【讨论】:

    • 但是当我使用这个函数删除一个节点并打印整个链表时,输出结果是正确的。你能解释一下为什么吗?
    • @2ndGenCore_i5 这只是未定义的行为。
    • 感谢您的洞察!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-08
    相关资源
    最近更新 更多