【问题标题】:Stack using linked list in C, freeing temp_node in pop function but still want to return it在 C 中使用链表堆栈,在 pop 函数中释放 temp_node 但仍想返回它
【发布时间】:2021-11-23 06:17:38
【问题描述】:

我正在使用 C 中的链表实现一个堆栈,我偶然发现了两个问题:

  1. 我需要stack_pop 函数返回一个有效值temp,即临时节点/单元,因此我无法释放它。所以,1)你认为为每个 pop 函数调用释放每个节点是否比使用 stack_destroy() 直到结束更好 2)我怎样才能同时实现 free(temp) 并在 stack_pop 中同时返回它?

  2. 我的实现在stack_pushstack_pop 函数中都不使用exit(1) 有多糟糕?

这是实现:

//// Stack

// Linked list
typedef struct {
    int data;
    Cell* next;
} Cell;

struct stack_l {
    size_t count;
    Cell *top;
};
typedef struct stack_l *Stack;

【问题讨论】:

  • 您可以实现两个独立的函数:const Cell *stack_peek(Stack stack) 访问/读取顶部项目的内容,void stack_pop(Stack stack) 从堆栈中删除顶部项目。
  • 好吧,我只想要接口:结构栈,push,pop,检查是否为empy。我没有很好地做到这一点?
  • 您描述的接口是有用且足够的,只要您的堆栈保留简单的值,例如单个 int。但是,如果您需要保留一些更大的数据(例如带有文本标签的 3D 点),使用指针访问它可能比复制到临时变量然后在 return 语句中再次复制临时变量更容易。
  • 你会如何在我的实现中解决这个问题?
  • stack_pop 或 stack_removetop:Cell*top=stack->top; if (top) {stack->top=top->next; free(top);}

标签: c data-structures memory-management stack


【解决方案1】:

您已将 stack_pop 声明为返回 int,但您试图返回一个没有意义的 Cell *

将弹出单元格中的值复制到局部变量,释放弹出单元格,然后返回值。

    temp = stack->top;
    stack->top = stack->top->next;
    temp->next = NULL;
    stack->count--;
    int val = temp.data;
    free(temp)
    return val;

此外,在 stack_pushstack_pop 中调用 exit 是没有意义的,因为这会结束程序。

【讨论】:

  • 还有==应该是=
  • 谢谢,您认为实现是否简短正确?
  • @pzii22 太复杂了。看我的回答——尤其是第二部分
  • 好吧,复杂的意义何在?我只是遵循标准的书籍实现。我还通过将节点和堆栈结构分开来使其更清晰。
【解决方案2】:

我认为这有点过于复杂了。你只需要记住之前的堆栈指针。没有别的了

typedef struct stack
{
    int data;
    struct stack *prev;
}stack;


stack *push(stack **sp, int data)
{
    stack *new = malloc(sizeof(*new));
    if(new)
    {
        new -> prev = *sp;
        new -> data = data;
        *sp = new;
    }
    return new;
}

int isempty(stack *sp)
{
     return !stack_pointer;
}

int pop(stack **sp)
{
    stack *new;
    int result = 0;
    if(sp && *sp)
    {
        result = (*sp) -> data;
        new = (*sp) -> prev;
        free(*sp);
        *sp = new;
    }
    return result;
}

int main(void)
{
    stack *stack_pointer = NULL;
    int result;

    push(&stack_pointer, 1);
    push(&stack_pointer, 2);
    push(&stack_pointer, 3);

    do
    {
        result = pop(&stack_pointer);
        printf("%d\n", result);
    }while(stack_pointer)   ;
    printf("Stack was empty so the loop has exited\n");
}

【讨论】:

  • 但我需要使用下一个,而不是上一个。做双链表的时候我会用prev。
  • @pzii22 我想你不明白堆栈是什么。您只能在顶部推动或从顶部弹出。您只需要知道堆栈上的当前位置并引用之前的位置即可。根据定义,没有其他东西作为堆栈不能被遍历。它是先进先出队列。,
  • 是的,这就是堆栈,这就是我正在做的我的实现,不是吗?
  • 你尝试这样做的方式很奇怪。看看我的实现与你的相比有多简单和合乎逻辑
  • 好的,但我需要一个看起来像这样的接口:结构堆栈、推送、弹出并检查是否为空。我没有很好地做到这一点?
猜你喜欢
  • 2016-10-24
  • 2016-10-15
  • 2021-03-18
  • 2015-10-08
  • 1970-01-01
  • 2011-09-08
  • 2013-12-21
  • 2020-02-14
  • 2012-05-24
相关资源
最近更新 更多