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函数的核心问题:
- 形参
s是栈顶指针的副本,修改s = s->next只会改变副本,无法影响main函数里的root,导致第二次pop时仍操作已被释放的旧栈顶内存,属于非法访问。 - 代码中
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
相关产品推荐
相关产品推荐

