如何修复C语言中缀转后缀计算器出现的segmentation fault错误
问题根因
段错误的核心触发原因是中缀转后缀的过程中,你给postfix字符串数组赋值的内容类型错误,导致后缀求值时is_operand函数访问非法内存地址,具体可拆解为以下几处错误:
postfix数组元素类型不匹配:你定义的postfix是char**类型,每个元素都应为指向字符串的指针,但你在inftopost函数中处理运算符时,直接把char类型的运算符ASCII值赋值给了postfix[counter]。相当于把字符值当成了内存地址,后续evaluate_postfix_expression调用is_operand时,会尝试访问这个非法地址,直接触发段错误。- 运算符栈使用逻辑错误:你当前用
double_stack存储的是运算符的ASCII值,但is_openbracket_stack、op_precedence函数的逻辑却把栈中取出的值当成了原args数组的索引去访问,比如你push了(的ASCII值40,后续就会去访问args[40],只要你的输入参数少于40个元素,就会直接越界触发段错误。 - 无用内存分配:
evaluate_infix_expression中你先给postfixmalloc了一块内存,接着又把inftopost的返回值赋值给postfix,之前malloc的内存直接泄漏。 - 函数调用参数不匹配:
op_precedence函数定义的第二个参数是char** infix,但你调用时传的是*args[i],也就是char类型,类型完全不匹配,运行时逻辑完全混乱。 - 后缀数组长度计算错误:你计算的
infix_size = nargs - 左括号数,但实际上左右括号都不会出现在后缀表达式中,正确计算应该是nargs - 2*括号对数,否则会给后缀求值函数传错参数长度,也可能触发越界访问。
修复方案
- 调整运算符栈逻辑:运算符栈中要么存储运算符对应的字符串指针,要么存储运算符在原
args数组的索引,不要直接存储ASCII值。比如选择存索引的话,push操作就传当前遍历的下标i,而不是*args[i]。 - 修正
postfix数组的赋值逻辑:给postfix[counter]赋值的时候,要么传递原args数组中对应的字符串指针,要么自己构造对应的单字符字符串,保证每个元素都是合法的char*类型。 - 删除
evaluate_infix_expression中多余的postfixmalloc语句,避免内存泄漏。 - 修正
op_precedence的参数传递,保证入参类型和函数定义匹配。 - 修正后缀表达式长度的计算逻辑,统计左右括号的总数量,用
nargs减去总括号数得到正确的后缀数组长度。
内容的提问来源于stack exchange,提问作者Karthik Venkat
相关产品推荐
相关产品推荐

