链表堆栈中的Pop函数导致分段错误-C

链表堆栈中的Pop函数导致分段错误-C,c,linked-list,stack,C,Linked List,Stack,我正在使用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;

我正在使用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;

}
推送功能在100%的时间内工作。如果堆栈中有多个值,则pop函数可以工作,但如果堆栈中只有一个值,则会导致分段错误。 根据我的调试器,问题出在带有

prev->next=NULL; 

有人能帮我理解问题是什么吗?

如果只有一个节点,则在pop()中,prev始终为空。因此,在
prev->next=NULL
之前放置一个条件


另外还有一个错误:如果有0个节点,
curr
在pop()中也是空的,所以您可能也想处理这个问题。

如果只有一个节点,则pop()中的
prev
始终为空。因此,在
prev->next=NULL
之前放置一个条件


另外还有一个bug:如果有0个节点,
curr
在pop()中也是空的,所以您可能也想处理它。

正如@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;

}

正如@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;

}

如果
prev
为空,则不希望尝试将
prev->next
设置为
NULL
。此外,如果删除唯一的节点,则需要将
*hd
设置为
NULL
。并且在调用
popFromTop
之前需要进行空检查。这与实际问题无关,但为什么要使用列表的尾部作为堆栈的顶部,因为它需要遍历pop和push的完整列表?这是低效的。使用列表的头部作为堆栈的顶部,以便push和pop都可以立即访问它,而无需任何遍历。如果
prev
为NULL,则不希望尝试将
prev->next
设置为
NULL
。此外,如果删除唯一的节点,则需要将
*hd
设置为
NULL
。并且在调用
popFromTop
之前需要进行空检查。这与实际问题无关,但为什么要使用列表的尾部作为堆栈的顶部,因为它需要遍历pop和push的完整列表?这是低效的。使用列表的头部作为堆栈的顶部,这样push和pop都可以立即访问它,而无需任何遍历。非常感谢!这很有效。我错过了基本案例和DavidSchwartz指出的问题。非常感谢!这很有效。我错过了基本案例和DavidSchwartz指出的问题。