C语言后缀转中缀代码出现Segmentation Fault及栈显示异常问题
问题分析与修复方案
1. 栈元素显示异常的原因
你的栈stk存储的是字符指针,但push的是临时复合字面量(比如(char [2]){ a[i], '\0' })和main里的局部数组nn:
- 复合字面量的生命周期仅限于所在的表达式语句,执行完push后,临时数组会被销毁,栈里的指针变成野指针。
- 每次运算时push的
nn是同一个局部数组的地址,栈里所有元素都指向同一块内存,所以display时看起来都是栈顶内容。
2. Segmentation Fault的原因
执行strcat(nn, y)时,y是从栈里取出的指针,而这个指针指向的是已销毁的临时复合字面量(野指针),访问野指针会触发段错误。
修复后的代码
#include <stdio.h> #include <string.h> #include <ctype.h> #include <stdlib.h> // 新增malloc头文件 #define MAX 20 char *stk[MAX], a[MAX]; int t = -1; void push(char *x); void pop(); void display(); int main() { int i = 0; char *x, *y, nn[MAX]; printf("enter expression:"); fgets(a, MAX, stdin); // 替换gets,避免缓冲区溢出 // 去掉fgets读取的换行符 size_t len = strlen(a); if (len > 0 && a[len-1] == '\n') { a[len-1] = '\0'; } while (a[i] != '\0') { if (isdigit(a[i])) { // 为单个字符分配内存,复制内容 char *digit = malloc(2 * sizeof(char)); digit[0] = a[i]; digit[1] = '\0'; push(digit); } else { display(); pop(); x = stk[t]; pop(); y = stk[t]; snprintf(nn, MAX, "(%s%c%s)", y, a[i], x); // 用snprintf更安全 // 为拼接后的字符串分配内存,复制内容 char *expr = malloc(strlen(nn) + 1); strcpy(expr, nn); push(expr); // 释放弹出的两个操作数内存,避免泄漏 free(x); free(y); } i++; } printf("%s\n", stk[0]); // 释放最终结果的内存 free(stk[0]); } void push(char *x) { t = t + 1; stk[t] = x; printf("curtop %d:%s\n", t, stk[t]); } void pop() { t = t - 1; } void display() { if (t >= 1) { // 增加边界检查,避免t-1越界 printf("stack elements: top->%s, %s\n", stk[t], stk[t - 1]); } else if (t == 0) { printf("stack elements: top->%s\n", stk[t]); } else { printf("stack is empty\n"); } }
关键修复点
- 替换临时指针为动态分配内存:用
malloc为每个操作数和表达式分配独立内存,确保指针指向的内容不会被销毁。 - 替换
gets为fgets:避免缓冲区溢出,同时处理换行符。 - 用
snprintf替代多次strcat:更安全,避免缓冲区溢出,代码更简洁。 - 增加内存释放:弹出操作数后及时释放内存,避免内存泄漏。
- display函数增加边界检查:防止栈为空或只有一个元素时访问
stk[t-1]导致越界。
内容的提问来源于stack exchange,提问作者Ancel Jomon
相关产品推荐
相关产品推荐

