Функция Pop в стеке связанных списков приводит к ошибке сегментации- C

#c #linked-list #stack

#c #связанный список #стек

Вопрос:

Я создаю стек, используя связанный список на C. Код выглядит следующим образом:

 struct node{
    int xposition;
    int yposition;
    struct node* next;
};

void pushToTop(struct node** hd, int x, int y){
    struct node* curr= *hd;
    struct node* prev=NULL;

    while(curr!=NULL){
        prev=curr;
        curr= curr->next;   
    }
    struct node* ptr= (struct node*)malloc(sizeof(struct node));
    ptr->xposition=x;
    ptr->yposition=y;
    ptr->next=curr;

    if(prev==NULL){
        *hd= ptr;}
    else{
        prev->next=ptr;
    }
}

void popFromTop(struct node** hd ){

    struct  node* curr= *hd;
    struct node* prev=NULL;
    while ( curr->next !=NULL) {
        prev=curr;
        curr=curr->next;
    }

    free(curr);
    prev->next= NULL;

}
  

Функция Push работает в 100% случаев. Функция pop работает, если в стеке есть несколько значений, но приводит к ошибке сегментации, когда в стеке есть одно значение.
Согласно моему отладчику, проблема заключается в методе popFromTop с

 prev->next=NULL; 
  

Может кто-нибудь, пожалуйста, помочь мне понять, в чем проблема?

Комментарии:

1. Если prev значение равно NULL, вы не хотите пытаться установить prev->next значение NULL . Кроме того, если вы удалите единственный узел, вам нужно установить *hd значение NULL .

2. И перед вызовом требуется пустая проверка popFromTop .

3. Не имеет отношения к фактическому вопросу, но почему вы используете хвост списка в качестве вершины стека, поскольку для этого требуется обход всего списка как для pop, так и для push? Это неэффективно. Используйте начало списка в качестве вершины стека, чтобы и push, и pop имели к нему немедленный доступ без какого-либо обхода.

Ответ №1:

Как уже упоминалось в комментариях @DavidSchwartz. Добавьте условие if.

 void popFromTop(struct node** hd ){

    struct  node* curr= *hd;
    //Base condition to handle empty list
    if(*hd == NULL)
        return;

    struct node* prev=NULL;
    while ( curr->next !=NULL) {
        prev=curr;
        curr=curr->next;
    }

    free(curr);
    if(prev != NULL)
       prev->next= NULL;
    else 
       *hd = NULL;

}
  

Комментарии:

1. Большое вам спасибо! Это работает. Мне не хватало базовых вариантов и проблемы, на которую указал @DavidSchwartz.

Ответ №2:

Если есть только один узел, in pop() prev всегда имеет значение NULL . Так что поставьте условие раньше prev->next = NULL .

Также есть еще одна ошибка: если узлов 0, curr в pop() также NULL, поэтому вы можете захотеть справиться и с этим.