You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C语言链表栈pop函数二次调用失效,求修复方案

链表栈pop函数的问题修复

原代码

struct n {
    int data;
    struct n* next;

};
typedef struct n node;

node* push(node* s, int x) {
    node* temp;// temporary element
    temp = (node*)malloc(sizeof(node));
    if (temp == NULL) {

        printf("not enough memory.");
        return -1;
    }


   // creates a new element that stores the data and pointed by the root pointer
    temp->data = x;
    temp->next = s;
    s = temp;
    return s;

}
int pop(node* s) {
    if (s == NULL) {
        printf("Stack is empty\n");
        return -1;
    }
    // create a temporary elements points the root pointer.
    // after iteration temporary elements will be deleted.
    node* temp = (node*)malloc(sizeof(node));
    temp = s;
    int rvalue = temp->data;
    s = s->next;
    free(temp);
    return rvalue;

}

int main() {
    node* root = NULL;
    root = push(root, 10);
    root = push(root, 20);
    root = push(root, 30);

    printf("%d\n", pop(root));
    printf("%d\n", pop(root));
    return 0;
}

问题分析

  • push函数通过返回新的栈顶指针更新栈,这是正确的——因为C语言是值传递,修改形参s不会影响实参root,必须返回新指针让实参接收。
  • pop函数的核心问题:
    1. 形参s是栈顶指针的副本,修改s = s->next只会改变副本,无法影响main函数里的root,导致第二次pop时仍操作已被释放的旧栈顶内存,属于非法访问。
    2. 代码中node* temp = (node*)malloc(sizeof(node));完全多余,随后直接将temp赋值为s,造成malloc的内存泄漏。

修复方案

方案1:使用指针的指针(传递栈顶指针的地址)

让pop函数直接修改实参指针的值:

int pop(node** s) {
    if (*s == NULL) {
        printf("Stack is empty\n");
        return -1;
    }
    node* temp = *s; // 直接指向栈顶,无需额外malloc
    int rvalue = temp->data;
    *s = (*s)->next; // 修改实参指针,指向新的栈顶
    free(temp);
    return rvalue;
}

// main函数中调用方式修改为:
printf("%d\n", pop(&root));
printf("%d\n", pop(&root));

方案2:返回新的栈顶指针(和push函数风格一致)

通过返回值更新栈顶,弹出的值用指针参数传递:

node* pop(node* s, int* rvalue) {
    if (s == NULL) {
        printf("Stack is empty\n");
        *rvalue = -1;
        return s;
    }
    node* temp = s;
    *rvalue = temp->data;
    s = s->next;
    free(temp);
    return s;
}

// main函数中调用方式修改为:
int val;
root = pop(root, &val);
printf("%d\n", val);
root = pop(root, &val);
printf("%d\n", val);

额外优化点

  • push函数中return -1;不合适,返回类型是node*,应返回NULL并配合errno标记内存分配失败。
  • 程序结束前需遍历栈释放所有节点,避免内存泄漏。

内容的提问来源于stack exchange,提问作者trgtulas

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 05:53:14