简体   繁体   English

如何删除 C 程序中的分段错误?

[英]How do I remove my segmentation faults in my C program?

I am trying to program a calculator that converts a an infix expression to a postfix expression and then evaluates the postfix expression.我正在尝试编写一个计算器,将中缀表达式转换为后缀表达式,然后计算后缀表达式。 I have included my code here for your reference.我在这里包含了我的代码供您参考。

My postfix code works perfectly fine as I have tested it on its own.我的 postfix 代码运行良好,因为我已经对其进行了单独测试。 But when I use the postfix code in my infix file for evaluation purposes, I get segmentation faults.但是当我在中缀文件中使用后缀代码进行评估时,我会遇到分段错误。

I have tried using gdb to debug my segfaults and it points me towards my is_operand() function in my postfix file.我曾尝试使用 gdb 调试我的段错误,它指向我的后缀文件中的 is_operand() 函数。 I backtraced to see how it got to that function, and I noticed that when my infix program calls the postfix_evaluate function, it calls this is_operand() function which gives me this error.我回溯以查看它是如何到达该函数的,并且我注意到当我的中缀程序调用 postfix_evaluate 函数时,它调用了这个 is_operand() 函数,这给了我这个错误。 I have no idea how to fix this issue as I'm relatively new to C coding.我不知道如何解决这个问题,因为我对 C 编码比较陌生。 Would appreciate some help!希望得到一些帮助!

My infix.c file:我的 infix.c 文件:

 #include "infix.h"
  

// evaluate expression stored as an array of string tokens
double evaluate_infix_expression(char ** args, int nargs) {
  // Write your code here
  char ** postfix = malloc(sizeof(char*) * nargs);
  postfix = inftopost(args, nargs);
  
  int count=0;
  for(int i=0;i<nargs;i++){
    if(is_openbracket(*(args+i))){
      count++;
    }
  }
  
  int infix_size = nargs - count;
  double final = evaluate_postfix_expression(postfix, infix_size);
  return final;
}

//--------------------------------------------------------

char ** inftopost(char** args, int nargs){
  char ** postfix = malloc(sizeof(char*) * nargs);
  struct double_stack* infix = double_stack_new(nargs);
  int counter=0;  
  
  for(int i=0;i<nargs;i++){
    if(is_operand(args[i])){
      postfix[counter]=args[i];
      counter++;
    }
    else if(is_openbracket(args[i])){
      double_stack_push(infix,'(');
    }
    else if(is_operator(args[i])){
      while(op_precedence(infix, *args[i], infix)){
        char flag3 = double_stack_pop(infix);
        postfix[counter]= flag3;
        counter++;
      }
      double_stack_push(infix, *args[i]);
    }
    else if(is_closedbracket(args[i])){
      int flag;
      while(!is_openbracket_stack(infix, args)){
        char flag = double_stack_pop(infix);
        postfix[counter] =flag;
        counter++;
      }  
      double_stack_pop(infix);
    }
  }
  
  int top = infix->items[infix->top-1];
  int flag2;
  
  while(is_operator(args[top])){
    int top = infix->items[infix->top-1];
    char flag2 = double_stack_pop(infix);
    postfix[counter] = flag2;
    counter++;
  }
  return postfix;
}



bool is_openbracket(char * token){
  if(token[0] == '('){
     return true;
  }
  return false;
}

bool is_closedbracket(char * token){
  if( token[0] == ')'){
    return true;
  }
  return false;
}

bool is_openbracket_stack(struct double_stack * input, char ** infix){
  int top = input->items[input->top-1];
  if(infix[top][0] == '('){
    return true;
  }
  return false;
}

bool op_precedence(struct double_stack * input, char**infix, char * token){
  int top = input->items[input->top-1];
  int top_stack_precedence =0;
  if(infix[top][0] == '^'){
    top_stack_precedence = 4;
  }else if((infix[top][0] == '*') || (infix[top][0] == '/')){
    top_stack_precedence = 3;
  }else if((infix[top][0] == '+') || (infix[top][0] == '-')){
    top_stack_precedence = 2;
  }
  
  int token_precedence =0;
  if(token[0] == '^'){
    token_precedence = 4;
  }else if((token[0] == '*') || (token[0] == '/')){
    token_precedence = 3;
  }else if((token[0] == '+') || (token[0] == '-')){
    token_precedence = 2;
  }
  
  if(token_precedence>=top_stack_precedence){
    return true;
  }
  return false;
}

My postfix.c file:我的 postfix.c 文件:

#include "postfix.h"

bool is_operator(char * token){
    if(token[0] == '+' || token[0]=='-' || token[0]== 'X' || token[0] == '/' || token[0] == '^'){
      return true;
    }
  return false;
}

bool is_operand(char*token){
  if(token[0]>='0' && token[0]<='9'){
    return true;
  }else if((token[0]=='-' || token[0]=='.') && (*(token+1)<='9' && *(token+1)>='0')){
    return true;
  }
  return false;
}


// evaluate expression stored as an array of string tokens
double evaluate_postfix_expression(char ** args, int nargs) {
  // Write your code here
  struct double_stack *stack =  double_stack_new(nargs);
  
  for(int i=0;i<nargs;i++){
    if(is_operand(*(args+i))){
      double_stack_push(stack,atof(*(args+i)));
    }
    
    else if( is_operator(args[i])) {
      double token, op1, op2;
      op2 = double_stack_pop(stack);
      op1 = double_stack_pop(stack);
      char operator_check = args[i][0];
      switch (operator_check){
        case  '+': 
          token = op2+op1;
          double_stack_push(stack,token);
          break;
        
        case '-':
          token = op1-op2;
          double_stack_push(stack,token);
          break;
          
        case 'X':
          token = op1*op2;
          double_stack_push(stack,token);
          break;
          
        case '/':
          token= op1/op2;
          double_stack_push(stack,token);
          break;
          
        case '^':
          token= pow(op1,op2);
          double_stack_push(stack,token);
          break;
          
        default: break;
      }
    }
  }

  return double_stack_pop(stack);
}

I havent included my .h files here, but I do have all necessary headerfiles and other necessary stuff.我没有在这里包含我的 .h 文件,但我有所有必要的头文件和其他必要的东西。

  1. malloc(nargs * sizeof(char *)) allocates space for an array of pointers, it does not allocate space for any of those pointers. malloc(nargs * sizeof(char *))为指针数组分配空间,它不会为任何这些指针分配空间。 You need to do something like postfix[i] = malloc(... * sizeof(char)) for every element of your array before trying to index into any of those strings.在尝试索引任何这些字符串之前,您需要对数组的每个元素执行类似postfix[i] = malloc(... * sizeof(char))操作。
  2. After you assign postfix to the result of malloc , you should not reassign it (you do this on the line postfix = inftopost(args, nargs) ).在将postfix分配给malloc的结果后,您不应重新分配它(您在postfix = inftopost(args, nargs)行上执行此操作)。 Otherwise, you are simply 'throwing away' the result of your malloc.否则,您只是在“扔掉” malloc 的结果。

As a general point of guidance, you should try to only use malloc and free within initialization functions.作为一般指导,您应该尝试仅在初始化函数中使用mallocfree For example, you could write the functions create_stack and destroy_stack .例如,您可以编写函数create_stackdestroy_stack All other stack methods then take a stack as a first argument, and perform some operation on that stack (popping, pushing, etc.).所有其他堆栈方法然后将堆栈作为第一个参数,并在该堆栈上执行一些操作(弹出、推送等)。

If you would like more elaboration on program design in C please leave a comment.如果您想更详细地了解 C 中的程序设计,请发表评论。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM