Ошибка сегментации (ядро сброшено) для конкретного случая - PullRequest
0 голосов
/ 09 января 2020

Я практикую двусвязный список. В этой программе все, кажется, работает нормально. В функции 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);
    }

1 Ответ

0 голосов
/ 09 января 2020

У вас проблема с индексом.

Очевидно, вы хотите, чтобы первый индекс был равен 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);
     }   

Так что это перекрывает элемент головки и вызывает ошибку сегмента, потому что головка не имеет элемента prev.

Совет: используйте индексирование нуля

Кстати: никогда не делайте

        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;
        }
...