Почему 17 символов в моей выходной строке заменяются на «о»?

#c #math

Вопрос:

Я пытался написать простой код, который вычисляет простые математические выражения, и я просто наткнулся на эту ошибку. Я пробовал разные способы найти проблему, но не смог. Мне это кажется нормальным, но когда я его выполняю, он заменяет 17 символов (индекс 16) строки » res » на «o» или просто удаляет его.

Этот фрагмент кода я написал для преобразования выражения из инфикса в постфикс :

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

char * ascan()
{
    char * s, c;
    int len = -1;

    s = (char *)malloc(sizeof(char));

    while (scanf("%c", amp;c) == 1)
    {
        if(c == 'n')
            break;
        len  = 1;
        s = (char *)realloc(s, (len   1));
        s[len] = c;
        s[len   1] = '';
    }

    return s;
}

char * chcpy(char * str, char chr)
{
    int len = strlen(str);

    str[len] = chr;
    str = (char *)realloc(str, (len   1));
    str[len   1] = '';
    len  ;

    return str;
}

typedef struct stack stack;
struct stack
{
    char opr;
    stack * pre;
};

stack * createStack()
{
    stack * stk;

    stk = NULL;

    return stk;
}

stack * push(stack * top, char opr)
{
    stack * new = (stack *)malloc(sizeof(stack));
    new -> opr = opr;

    new -> pre = top;
    top = new;

    return top;
}

char pop(stack ** top)
{
    if ((*top) != NULL)
    {
        char opr = (*top) -> opr;

        stack * tmp = (*top);
        (*top) = (*top) -> pre;
        free(tmp);

        return opr;
    }

    return '';
}

char * evaluatePostfix(char * exp)
{
    char * pfe = (char *)malloc(sizeof(char));
    stack * ops = createStack();
    int i = 0, p = 0;

    while (exp[i] != '')
    {
        if (exp[i] == '(')
            p  ;
        else if (isdigit(exp[i]))
            pfe = chcpy(pfe, *(exp   i));
        else if (exp[i] == ')')
        {
            p--;

            if (ops != NULL)
            {
                pfe = chcpy(pfe, ' ');
                pfe = chcpy(pfe, pop(amp;ops));
            }
        }
        else if (exp[i] == ' ' || exp[i] == '-' || exp[i] == '*' || exp[i] == '/')
        {
            pfe = chcpy(pfe, ' ');

            ops = push(ops, exp[i]);
        }

        i  ;
    }

    while (ops != NULL)
    {
        pfe = chcpy(pfe, ' ');
        pfe = chcpy(pfe, pop(amp;ops));
    }

    if (p < 0)
        return NULL;

    return pfe;
}

int main()
{
    char * exp = ascan(), * res;

    res = evaluatePostfix(exp);

    printf("%sn", res);

    return 0;
}
 

Я действительно не знаю, почему это влияет только на этот точный символ, и я не знаю, является ли это именно ошибкой распределения, но если это так, пожалуйста, помогите мне ее решить.

Ввод :

 10*(2 8*(3-2))
 

Выход :

 10 2 8 3 2 - *  o*
                ^
 

Комментарии:

1. какое выражение вы пытаетесь вычислить?

2. @AsafItach Я только что добавил пример ввода с выводом

3. @AsafItach да, проблема заключалась в нулевом символе. Кстати, извините, что не включил ascan (), я не думал, что было бы полезно опубликовать его

Ответ №1:

    int len = strlen(str);

   *(str   len) = chr;
   str = (char *)realloc(str, (len   1));
   *(str   len   1) = '';
 

Здесь вы записываете завершающий нулевой символ за пределами выделенной памяти. Исправленный:

     int len = strlen(str);
    str[len  ] = chr;
    str = realloc(str, len   1);
    str[len] = '';
    return str;
 

И есть еще одна проблема — вы забыли инициализировать *pfe = ''; evaluatePostfix его перед добавлением .

Комментарии:

1. Также смотрите другой вопрос.

2. Да, спасибо, я не заметил другого.

3. Кстати, почему он печатает именно «о», а не другой символ, я пробовал разные входные данные, и это всегда «о».

4. Это может быть проанализировано в среде выполнения, где ошибка проявляется так, как вы описываете, что является лишь одним из многих возможных вариантов поведения. Моя система так себя не ведет, поэтому, извините, я не могу найти причину для вашего наблюдения.