ненормальное поведение при отображении массива char в C ++ после инициализации объекта - PullRequest
1 голос
/ 06 февраля 2020

main ():

char inp[] = "(A+B)/(C*D))";

Infix i;
cout << "In main: " << inp  /* + ')' */  << endl << endl;

Вот Infix конструктор:

Infix() {
        push('(');
        cout << "Element In Stack: " << *returnElement(returnTop()) << endl;
        outputString = "";
        strcpy(operatorArray, "/*-+%");
        cout << "Operator Array: " << operatorArray << endl;

    }

Инфикс наследуется от класса 'Stack':

class Stack{
int top = -1;
char arr[100];

public:
    bool push(char);
    char pop();
    char peek();
    bool isEmpty();
    void displayAll();
    char returnTop() { return top;}
    char* returnElement(int i) {
        if(i > 98){
            cout << "StackOutOfIndex";
            return nullptr;
        }
        return &arr[i];
    }

};

Когда я запускаю код в main, он отображает необычный вывод:

Element In Stack: (
Operator Array: /*-+%
In main: +%


Stack Object Destroyed!

Но, если в main, если комментарий, строка, объявляющая объявление объекта 'Infix', код работает нормально:

In main: (A+B)/(C*D))

РЕДАКТИРОВАТЬ:

Класс стека

#include<iostream>

using namespace std;

class Stack{
    int top = -1;
    char arr[100];

    public:
        bool push(char);
        char pop();
        char peek();
        bool isEmpty();
        void displayAll();
        char returnTop() { return top;}
        char* returnElement(int i) {
            if(i > 98){
                cout << "StackOutOfIndex";
                return nullptr;
            }
            return &arr[i];
        }

};

bool Stack:: push(char elementToPush) {
    if(top > 98) {
        cout << "\nStack Overflow!!";
        return false;
    } else {
        arr[++top] = elementToPush;
        return true;
    }
}

char Stack:: pop() {
    if(top <= -1) {
        cout << "\nStack Underflow!!";
        return ' ';
    } else {
        return (arr[top--]);
    }
}

char Stack:: peek() {
    if(top > 98) {
        cout << "\nStack Overflow!!";
        return ' ';
    } else {
        return arr[top];
    }
}

bool Stack:: isEmpty() {
    return (top <= 0);
}

void Stack:: displayAll() {
    if(top <= -1) {
        cout << "null";
        return;
    }
    int i = top;
    while (i >= 0) {
        cout << arr[i] << " ";
        --i;
    }
    cout << "\n";
}

Infix Class

#include<iostream>
#include<cstring>
#include<D:\Programs\11Stack.cpp>

using namespace std;

class Infix : public Stack {
    string outputString;
    char operatorArray[];
    public:
        Infix() {
            push('(');
            cout << "Element In Stack: " << *returnElement(returnTop()) << endl;
            outputString = "";
            strcpy(operatorArray, "/*-+%");
            cout << "Operator Array: " << operatorArray << endl;

        }

        string infixToPostfix(char *, int);
        bool manupulateOperator(char, int); 
        int checkPrecedence(char);

        ~Infix() {
            cout << "\nStack Object Destroyed!" << endl;
        }
};

string Infix:: infixToPostfix(char *str, int size) {
    cout << "\nGiven String: " << str << endl;
    int x;
    for(int i = 0; i < size; ++size) {
        x = str[i];
        if(x != ' ') {
            if(x == ')') {
                while(returnTop() != '(') {
                    cout << pop() << " popped!\n";
                }

                    cout << pop() << " popped!\n";
            } else if(isalpha(x)) {
                cout << x;
        } /* else{ // scanned character is an operator
            if(manupulateOperator(x, i)) {

            } else {
                return " ";
                }
            } */
        }
    }

    return outputString;
}

bool Infix::manupulateOperator(char c, int position) {
    try {
        char topElement = *returnElement(returnTop());
        if(checkPrecedence(c) == -1) {
            cout << "\nErr\n";
        }else if((checkPrecedence(c) > checkPrecedence(topElement)) || returnTop() == 0) {
            push(c);
            cout << c << " pushed!\n";
        }
    } catch(std::exception e) {
        std::cerr << e.what() << '\n';
        return false;
    } catch (char* Ce) {
        cout << Ce << endl;
    }

    return true;
}

int Infix::checkPrecedence(char c) {
    /* 
        + -> 1
        - -> 1
        * -> 2
        / -> 2
        % -> 2
    */
    switch(c) {
        case '+':
            return 1;

        case '-':
            return 1;

        case '*':
            return 2;

        case '/':
            return 2;

        case '%':
            return 2;

        default:
            // throw "Illegal Operator Detected!";
            cout << "Illegal Operator Detected: " << c << endl;
            return -1;

    }
}

int main() {
    cout << endl;
    int x = 1;

    char inp[] = "(A+B)/(C*D))";

    //Infix i;
    cout << "In main: " << inp  /* + ')' */  << endl << endl;

    // cout << i.infixToPostfix(input + ')', sizeof(input));
/*     for(int i = 0; i < strlen(inp); ++i) {
        cout << inp[i];
    }
 */
    return 0;
}

Ответы [ 3 ]

0 голосов
/ 06 февраля 2020

Вы объявляете operatorArray как массив char, но вы не выделяете для него память! Итак, когда вы затем вызываете strcpy(operatorArray, "/*-+%"); в конструкторе Infix, вы вызываете неопределенное поведение , пытаясь скопировать данную строковую константу в память, которая не была назначена - и это, похоже, перезаписывает массив inp[], объявленный в вашем main.

Чтобы это исправить, я бы предложил дать вашему члену operatorArray определенный c размер, который будет достаточно большим, чтобы вместить любую строку, которую вы хотите скопируйте его - 8 символов будут работать в приведенном вами примере кода:

class Infix : public Stack {
    string outputString;
    char operatorArray[8]; // Make this member a REAL array of characters.
    //..
0 голосов
/ 06 февраля 2020

char operatorArray[]; не допускается в стандарте C ++.

Если вы не видите сообщение об ошибке, я бы порекомендовал изменить настройки компилятора, следуя стандартной форме языка, это сэкономило бы вам много времени.

0 голосов
/ 06 февраля 2020

Ваша переменная char operatorArray[] не имеет выделенной памяти при вызове вашего конструктора. Когда вы используете strcpy, вы пишете в место, где у вас нет разрешений в вашей памяти и, следовательно, на другую информацию.
Чтобы найти ошибки такого рода, я рекомендую использовать valgrind .

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