Ошибка сегментации в простом калькуляторе C - PullRequest
0 голосов
/ 14 марта 2019

Я столкнулся с ошибкой сегментации в простом калькуляторе c, который я пытаюсь создать. Предполагается, что калькулятор принимает формулу с +, x и квадратными скобками и выводит ответ. Реализация основана на двух массивах, которые работают как стеки, стек операндов и стек значений. Я изо всех сил пытаюсь исправить ошибку сегментации. Я приложил код ниже.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void pushValStack(int stack[], int *top, int value){
   *top++;
   stack[*top] = value;
}

int popValStack(int stack[], int *top){
   *top--;
   return stack[*top];
}

void pushOpStack(char *stack[], int *top, char *value){
   *top++;
   stack[*top] = value;
}

char *popOpStack(char *stack[], int *top){
   *top--;
   return stack[*top];
}

int main(int argc, char *argv[]){
   char *token;
   int tokenNumber = 1;
   int value[51];
   int *valueTop = 0;
   int valueOne,valueTwo;
   char *operand[51];
   int *operandTop = 0;
   char *operandOne;

   token = argv[tokenNumber];
   while (token != NULL){
      if (*token == '+' || *token == 'x' || *token == '['){
         pushOpStack(operand, operandTop, token);
      }
      else if (*token == ']'){
         while (*operand[*operandTop] != '['){
            operandOne = popOpStack(operand, operandTop);
            if (*operandOne == '+'){
               valueOne = popValStack(value, valueTop);
               valueTwo = popValStack(value, valueTop);
               pushValStack(value, valueTop, valueOne + valueTwo);
            }
            if (*operandOne == 'x'){
               valueOne = popValStack(value, valueTop);
               valueTwo = popValStack(value, valueTop);
               pushValStack(value, valueTop, valueOne * valueTwo);
            }
         }
      }
      else {
         pushValStack(value, valueTop, atoi(token));
      }
      tokenNumber++;
      token = argv[tokenNumber];
   }
   while (*operandTop != 0){
      operandOne = popOpStack(operand, operandTop);
      if (*operandOne == '+'){
         valueOne = popValStack(value, valueTop);
         valueTwo = popValStack(value, valueTop);
         pushValStack(value, valueTop, valueOne + valueTwo);
      }
      if (*operandOne == 'x'){
         valueOne = popValStack(value, valueTop);
         valueTwo = popValStack(value, valueTop);
         pushValStack(value, valueTop, valueOne * valueTwo);
      }
   }
   printf("\n%d",popValStack(value, valueTop));
}

Ответы [ 2 ]

0 голосов
/ 14 марта 2019

Вы объявляете количество int* переменных, но никогда не выделяете для них память. Вместо этого они должны быть int, поскольку они содержат индексы в стеке.

int valueTop = 0;
int operandTop = 0;

Тогда вы должны использовать эти переменные, вам не нужно разыменовывать их. Но когда вы передаете их функциям, которым необходимо обновить переменные, вы должны передать адрес переменной.

int main(int argc, char *argv[]){
    char *token;
    int tokenNumber = 1;
    int value[51];
    int valueTop = 0;
    int valueOne,valueTwo;
    char *operand[51];
    int operandTop = 0;
    char *operandOne;

    token = argv[tokenNumber];
    while (token != NULL){
        if (*token == '+' || *token == 'x' || *token == '['){
            pushOpStack(operand, &operandTop, token);
        }
        else if (*token == ']'){
            while (*operand[operandTop] != '['){
                operandOne = popOpStack(operand, &operandTop);
                if (*operandOne == '+'){
                    valueOne = popValStack(value, &valueTop);
                    valueTwo = popValStack(value, &valueTop);
                    pushValStack(value, &valueTop, valueOne + valueTwo);
                }
                if (*operandOne == 'x'){
                    valueOne = popValStack(value, &valueTop);
                    valueTwo = popValStack(value, &valueTop);
                    pushValStack(value, &valueTop, valueOne * valueTwo);
                }
            }
        }
        else {
            pushValStack(value, &valueTop, atoi(token));
        }
        tokenNumber++;
        token = argv[tokenNumber];
    }
    while (operandTop != 0){
        operandOne = popOpStack(operand, &operandTop);
        if (*operandOne == '+'){
            valueOne = popValStack(value, &valueTop);
            valueTwo = popValStack(value, &valueTop);
            pushValStack(value, &valueTop, valueOne + valueTwo);
        }
        if (*operandOne == 'x'){
            valueOne = popValStack(value, &valueTop);
            valueTwo = popValStack(value, &valueTop);
            pushValStack(value, &valueTop, valueOne * valueTwo);
        }
    }
    printf("\n%d",popValStack(value, &valueTop));
}
0 голосов
/ 14 марта 2019

operandTop - переменная-указатель типа int*.Вы инициализируете его как 0 (нулевой указатель) и никогда не назначаете ему другое значение.Любая попытка разыменования приведет к неопределенному поведению, вероятно, к ошибке сегментации.

Я запустил вашу программу под отладчиком без аргументов командной строки, и он умер в строке 61, while (*operandTop != 0){

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...