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

栈操作引发Segmentation fault问题及pop函数疑问求助

问题解答

上下文

检查输入表达式合法性后,将数组传入infix2postfix函数。在比较运算符优先级时,执行while (iprec(a[i]) < sprec(top->ch ))出现Segmentation fault,添加if(top!=NULL)条件后恢复正常,但将条件改为while (iprec(a[i]) <= sprec(top->ch ))后再次触发Segmentation fault。


问题1:如何解决该Segmentation fault问题?

你的代码存在多处逻辑错误,直接引发了段错误,以下是针对性修正方案:

1. 修复运算符优先级循环的空栈判断

原循环未先判断top是否为NULL,栈空时访问top->ch会直接触发空指针解引用错误。必须将top != NULL作为循环前置条件,利用C语言短路求值特性,避免非法内存访问:

while (top != NULL && iprec(a[i]) <= sprec(top->ch))

2. 修正括号匹配逻辑

  • 右括号判断错误:原代码把左括号[、{当成了右括号,应改为对应的右括号:
    else if (a[i] == ')' || a[i] == ']' || a[i] == '}')
    
  • 括号处理循环重复pop:原循环内调用两次pop(),会导致多弹出元素甚至栈提前为空,同时未区分不同类型括号的匹配关系,修正后:
    char target;
    switch(a[i]) {
        case ')': target = '('; break;
        case ']': target = '['; break;
        case '}': target = '{'; break;
        default: target = '\0';
    }
    char c;
    while (top != NULL && (c = pop()) != target) {
        pfix[k++] = c;
    }
    

3. 修复后缀数组空间越界问题

原代码char pfix[strlen(a)];的空间不足以存储终止符\0,应多分配一个字节:

char pfix[strlen(a) + 1];

修正后的完整函数示例

void infix2postpix(char a[])
{
    char pfix[strlen(a) + 1];
    int k = 0;
    for (int i = 0; a[i] != '\0'; i++)
    {
        if (Isopd(a[i]))
        {
            pfix[k++] = a[i];
        }
        else if (Isopr(a[i]) || a[i] == '(' || a[i] == '{' || a[i] == '[')
        {
            while (top != NULL && iprec(a[i]) <= sprec(top->ch))
            {
                pfix[k++] = pop();
            }
            push(a[i]);
        }
        else if (a[i] == ')' || a[i] == ']' || a[i] == '}')
        {
            char target;
            switch(a[i]) {
                case ')': target = '('; break;
                case ']': target = '['; break;
                case '}': target = '{'; break;
                default: target = '\0';
            }
            char c;
            while (top != NULL && (c = pop()) != target)
            {
                pfix[k++] = c;
            }
        }
    }
    while (top != NULL)
    {
        pfix[k++] = pop();
    }
    pfix[k] = '\0';
    printf("%s", pfix);
}

问题2:为何pop函数必须检查top是否为NULL?

核心原因

当栈为空时,top指针指向NULL,此时访问top->no或top->ch属于空指针解引用,是C语言的未定义行为,必然触发Segmentation fault。pop函数中的top == NULL检查是为了提前拦截空栈弹出操作,避免非法内存访问。

你遇到“每次触发段错误”的原因

这不是编译问题,是代码逻辑错误导致非空栈场景下也会触发空栈弹出:比如原代码括号处理循环中每次调用两次pop(),当栈内只剩匹配的左括号时,第一次pop()取出左括号,第二次pop()就会处理空栈,此时top为NULL,访问top->no直接触发段错误。此外,原运算符优先级循环未判断top != NULL,栈空时直接访问top->ch也会引发错误。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 00:45:59