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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 15:15:59