-3

The question is to convert a postfix expression to an infix expression using stacks and without stack library.

Im getting a statement after i run it and enter my postfix expression saying : "Process returned -1073740940 (0xC0000374) execution time : 5.538 s"

The second i enter my postfix expression, the computer freezes and takes up a few seconds and then gives the statement. It does not even return the infix expression.

I have absolutely no clue why. It also somestimes can take 30-40s just for this error to pop up.

Edit#1: Okay so as @churill said, the misplaced parenthesis was an issue. i corrected that. now im getting this error immediately: "terminate called after throwing an instance of 'std::bad_alloc' what(): std::bad_alloc"

My code: (Edited once)

#include <iostream>
#include <ctype.h>
const int MAX = 20;

using namespace std;

class Stack {
private:
    int top = -1;
    string arr[MAX];
public:
    bool isEmpty(){
        if (top == -1){
            return true;
        }
        else{
            return false;
        }
    }

    bool isFull(){
        if(top == MAX-1){
            return true;
        }
        else{
            return false;
        }
    }

    void push(string c){
        if(isFull()){ //Edited line 
            cout<<"Stack Overflow"<<endl;
        }
        else{
            top++;
            arr[top] = c;
        }
    }

    string pop(){
        string val = arr[top];
        arr[top] = '0';
        top--;
        return val;
    }

    string topele(){
        string topelement = arr[top];
        return topelement;
    }

    string display(){
        int i;
        for(i=top;i>=0;i--){
            cout<<arr[i]<<endl;
        }
    }

    bool isOperand(char c){
        if(c >= 'a' && c <= 'z'){
            return true;
        }
        else{
            return false;
        }
    }

    string posfixtoinfix(string postfix){
        Stack s;
        int i;
        int len = postfix.size();
        for(i=0;i<=len;i++){
            if(s.isOperand(postfix[i])){ //Edited line
                string op(1, postfix[i]);
                s.push(op);
            }
            else{
                string op1 = s.topele();
                s.pop();
                string op2 = s.topele();
                s.pop();
                string res = ("("+ (op2 + postfix[i] + op1) + ")");
                s.push(res);
            }
        }
        return s.topele();
    }

};

int main(){
    Stack s1;
    string postfix, infix;
    cout<<"Enter postfix expression: "<<endl;
    cin>>postfix;
    infix = s1.posfixtoinfix(postfix);
    cout<<"The infix expression is: "<<infix<<endl;

    return 0;

}

tripleee
  • 175,061
  • 34
  • 275
  • 318
  • Multiple possible causes in your code, but your symptoms are consistent with accessing an array element out of bounds. Look, in particular, at functions that access or modify `arr[top]`. Consider what each function would do if `top` initially has a value of `-1` (which is what it is initialised to by default). Additionally, your function `posfixtoinfix()` accesses elements of the string `postfix` with indices between `0` and `postfix.size()` inclusive - the latter is running past the end. More generally, learn how to step through your program with a debugger. – Peter Dec 31 '21 at 10:55
  • Sidenote to make your code more readable and easier to maintain: `if(condition) return true; else return false;` can be written as `return condition;` – Lukas-T Dec 31 '21 at 11:08
  • @Peter "the latter is running past the end." - What does this mean? – Aryan Raveshia Dec 31 '21 at 11:13
  • `s.isOperand(postfix[i]==true)` also looks like a misplaced parenthesis. So style tip #2: Don't write `if(condition == true)`, just use `if(condition)` – Lukas-T Dec 31 '21 at 11:26
  • @AryanRaveshia Your code is accessing `postfix[postfix.size()]` which gives undefined behaviour. – Peter Jan 01 '22 at 04:41

1 Answers1

0

For one, You have undefined behavior in your program. This is because you're going out of bounds when you wrote string op1 = s.topele(); at:

else{
        string op1 = s.topele(); //this will call topele
//...
}

Now the member funciton topele is called and you have

string topelement = arr[top]; //this will result in(when top = -1) undefined behavior and may crash the program

But note since top holds the value -1 by default, in the above snippet, you're essentially writing

string topelement = arr[-1];

which leads to undefined behavior and may result in a crash.

Remember that for a std::string the valid range of indexes is 0 to myString.length() - 1 (inclusive). When you use -1 as index, you get the character before the string, which is out of bounds and leads to undefined behavior.

Undefined behavior means anything1 can happen including but not limited to the program giving your expected output. But never rely(or make conclusions based) on the output of a program that has undefined behavior.


1For a more technically accurate definition of undefined behavior see this where it is mentioned that: there are no restrictions on the behavior of the program.

Jason
  • 36,170
  • 5
  • 26
  • 60
  • But `postfix` is not a `std::vector`, but a `std::string`. Access a `std::string` one past the end, e.g. `postfix[postfix.length()]` will not cause UB, but return the null-character `\0`. – Lukas-T Dec 31 '21 at 11:25
  • @churill i have updated the answer. check it out. – Jason Dec 31 '21 at 11:33
  • @churill Alright the code works perfectly now, the problem was the additional '=' sign in 'for(i=0;i<=len;i++){' as Peter also pointed out along with you guys, the last element of the len was taken into the loop but the loop started with 0, hence 0,1 and 2 were the indexes and not 0.1.2 and the extra 3 which does not exist. Thank you – Aryan Raveshia Dec 31 '21 at 12:35