在特定情况下出现分段故障(内核已转储)

问题描述 投票:0回答:1

我正在练习双向链表。在此程序中,一切似乎都正常。在Delete()函数中,当我尝试删除第一个节点时,该程序可以正常工作并删除第一个代码。但是,每当我给任何其他节点时,我总是会得到错误:分段错误(核心已转储)。有人可以告诉我我在做什么错吗?

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

    struct Node{
        struct Node *prev;
        int data;
        struct Node *next; 
    }*first = NULL;

    void create(int A[], int n){
        struct Node *t, *last;
        int i;

        first = (struct Node *)malloc(sizeof(struct Node));
        first->data = A[0];
        first->prev = first->next = NULL;
        last = first;

        for(i = 1; i < n; i++){
            t = (struct Node *)malloc(sizeof(struct Node));
            t->data = A[i];
            t->prev = last->next;
            t->next = NULL;
            last->next = t;
            last = t;
        }
    }   
    void Display(struct Node *p){
        while( p != NULL){
            printf("%d ",p->data);
            p = p->next;
        }
        printf("\n");
    }

    int Length(struct Node *p){
        int len = 0;
        while(p){
            len++;
            p = p->next;
        }
        return len;
    }

    void insert(int index, int key){
        struct Node *t, *p = first;
        int i;

        if(index < 0 || index > Length(p))
            return;
        t = (struct Node *)malloc(sizeof(struct Node));
        t->data = key;
        if(index == 0){
            if(p == NULL){
                t->prev = NULL;
                t->next = NULL;
                first = t;
            }
            else{
                t->prev = NULL;
                t->next = first;
                first->prev = t;
                first = t;
             }
            }
        else{
            for(i = 0; i < index - 1; i++) p = p->next;
            t->next = p->next;
            t->prev = p;
            if(p->next) p->next->prev = t;
            p->next = t;
        }
    }

    int Delete(struct Node *p, int index){
        int x = -1,i;
        if(index < 1 || index > Length(p))
            return -1;

        if(index == 1){
            first = first->next;
            if(first)first->prev = NULL;
            x = p->data;
            free(p);
        }
        else{
            for(i=0; i<index-1; i++)
            p=p->next;
            x=p->data;
            p->prev->next=p->next;
             if(p->next)
             p->next->prev=p->prev;
            free(p);
         }   
        return x;
    }

    void main(){
        int A[] = {2, 4, 6, 8, 10};
        create(A, 5);
        Display(first);
        printf("%d is deleted\n",Delete(first, 3));
        Display(first);
    }
c pointers linked-list doubly-linked-list
1个回答
0
投票

您的索引有问题。

显然您希望第一个索引为1-可以。

让我们调用索引为2的函数。

所以您将在这里结束:

    else{
        for(i=0; i<index-1; i++)
        p=p->next;
        x=p->data;
        p->prev->next=p->next;
         if(p->next)
         p->next->prev=p->prev;
        free(p);
     }   

再次是:

    else{
        for(i=0; i<2-1; i++) // notice
        p=p->next;
        x=p->data;
        p->prev->next=p->next;
         if(p->next)
         p->next->prev=p->prev;
        free(p);
     }   

    else{
        for(i=0; i<1; i++) // notice
        p=p->next;
        x=p->data;
        p->prev->next=p->next;  // arghh... seg fault
         if(p->next)
         p->next->prev=p->prev;
        free(p);
     }   

因此这与head元素重叠。

BTW:从不做

        for(i=0; i<index-1; i++)
        p=p->next;

将其更改为

        for(i=0; i<index-1; i++) p=p->next;

或更好

        for(i=0; i<index-1; i++)
        {
            p=p->next;
        }
© www.soinside.com 2019 - 2024. All rights reserved.