【问题标题】:How do I correctly perform a pop function in a linked list?如何在链表中正确执行弹出功能?
【发布时间】:2021-01-22 03:24:59
【问题描述】:

我在我的程序上运行了 GDB,我认为我的 pop 函数有问题,但我不完全确定我在该函数中的逻辑有什么问题?

似乎一切都很好地推入堆栈,但是当我们开始从堆栈中弹出值时,您可以看到程序失败。

我为链表的头部创建一个临时ptr,然后将链表的头部设置为下一个节点,然后释放我的临时指针。

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

#define SIZE 10
#define FALSE 0
#define TRUE  1

struct linkedStruct {
    int elem;
    struct linkedStruct *next;
};
 
typedef struct linkedStruct linked;
typedef linked *linkedPtr; 

void push(linkedPtr *hd, int val) {
    linkedPtr ptr = (linkedPtr)malloc(sizeof(linked));
    ptr->elem = val;
    ptr->next = *hd;
    *hd = ptr;
}

int isEmpty(linkedPtr hd) {
    if (hd == NULL)
        return TRUE;
    else
        return FALSE;
}
 
int top(linkedPtr hd) {
    return (hd->elem);
}

void pop(linkedPtr hd) {
    linkedPtr tmp = hd;
    hd = hd->next;
    free (tmp);
}

void show(linkedPtr hd) {
    while (hd != NULL) {
        printf("%d, ", hd->elem);
        hd = hd->next;
    }
    printf("\n");
}

int main(int argc, char **argv) {
    linkedPtr head = NULL;
    int i;
    int temp;

    /* push 10 random values onto the stack showing the stack growing */
    for (i = 0; i < SIZE; ++i) {
        temp = rand() % 100;
        printf("In main(): temp: %6d\n", temp);
        push(&head, temp);
        show(head);
   }

   printf("\n");

   /* remove the value from the stack */
   while (!isEmpty(head)) {
       printf("Top of stack value is: %d\n", top(head));
       pop(head);
   }
}

输出

In main(): temp:     83
83, 
In main(): temp:     86
86, 83, 
In main(): temp:     77
77, 86, 83, 
In main(): temp:     15
15, 77, 86, 83, 
In main(): temp:     93
93, 15, 77, 86, 83, 
In main(): temp:     35
35, 93, 15, 77, 86, 83, 
In main(): temp:     86
86, 35, 93, 15, 77, 86, 83, 
In main(): temp:     92
92, 86, 35, 93, 15, 77, 86, 83, 
In main(): temp:     49
49, 92, 86, 35, 93, 15, 77, 86, 83, 
In main(): temp:     21
21, 49, 92, 86, 35, 93, 15, 77, 86, 83, 

Top of stack value is: 21
Top of stack value is: 0
Top of stack value is: 17254288
Top of stack value is: 17254288
Top of stack value is: 17254288
Top of stack value is: 17254288
Top of stack value is: 17254288
Top of stack value is: 17254288
Top of stack value is: 0
double free or corruption (fasttop)

【问题讨论】:

标签: c


【解决方案1】:

您的pop 函数没有提供任何方法将head 的新值返回给调用者。所以在你的循环中,第二次循环中,head 仍然指向你在循环中第一次释放的对象。

请注意,不是将head 传递给push,而是将一个指向head指针 传递给push 函数?这样push就可以修改head。对pop 执行相同操作。

void pop (linkedPtr hd)
{
 linkedPtr tmp = hd;
 hd = hd->next; // This line doesn't do anything
 free (tmp);
}

注意标记的行如何修改hd,但hd 即将在pop 完成时超出范围。 hd 的新值没有做任何事情。

【讨论】:

    【解决方案2】:

    pop 函数应该接受一个指向头元素的指针并返回弹出的值:

    int pop(linkedPtr *headp) {
        linkedPtr tmp = *headp;
        int elem = tmp->elem;
        *headp = tmp->next;
        free(tmp);
        return elem;
    }
    

    typedef linked *linkedPtr; 中将指针隐藏在 typedef 后面是令人困惑且容易出错的。最好显式使用指针语法并将双指针作为linked **hd 处理。

    这是修改后的版本:

    #include <stdio.h>
    #include <stdlib.h>
    
    #define SIZE 10
    #define FALSE 0
    #define TRUE  1
    
    struct linkedStruct {
       int elem;
       struct linkedStruct *next;
    };
     
    typedef struct linkedStruct linked;
    
    void push(linked **headp, int val) {
        linked *ptr = (linked *)malloc(sizeof(*ptr));
        ptr->elem = val;
        ptr->next = *headp;
        *headp = ptr;
    }
    
    int isEmpty(const linked *hd) {
        return (hd == NULL);
    }
     
    int top(const linked *hd) {
        return hd->elem;
    }
    
    int pop(linked **headp) {
        linked *tmp = *headp;
        int elem = tmp->elem;
        *headp = tmp->next;
        free(tmp);
        return elem;
    }
    
    void show(const linked *hd) {
        while (hd != NULL) {
            printf("%d, ", hd->elem);
            hd = hd->next;
        }
        printf("\n");
    }
    
    int main(int argc, char **argv) {
        linkedPtr head = NULL;
        int i;
        int temp;
    
        /* push 10 random values onto the stack showing the stack growing */
        for (i = 0; i < SIZE; ++i) {
            temp = rand() % 100;
            printf("In main(): temp: %6d\n", temp);
            push(&head, temp);
            show(head);
        }
    
        printf("\n");
    
        /* remove the value from the stack */
        while (!isEmpty(head)) {
            printf("Top of stack value is: %d\n", top(head));
            pop(&head);
        }
        return 0;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-11-16
      • 1970-01-01
      • 2014-12-18
      • 2021-05-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多