c++segmentation-faultpostfix-notationinfix-notationshunting-yard

segmentation fault when assigning a string to stack.top()


I have been working on a basic calculator that can take in complicated mathematical expressions such as:(2-4)*7/(3/4) etc etc

I am using an implementation of the shunting yard algorithm...

I am on a linux OS. using the gdb debugger I have isolated a segmentation fault to one function. using cout statements I have isolated it further to a single line..however I cannot fathom why this line is giving me a segfault..I will give more info on exactly where in just a moment, first here is some code..

bool infixToPostfix(const std::vector<std::string>& inputTokens, const int& size, std::vector<std::string>& strArray){
     std::cout << "1" << std::endl; 
     bool success = true;
     std::list<std::string> out;
     std::stack<std::string> st;

for(int i = 0; i < size; i++){
    std::cout << "2\n";
    const std::string token = inputTokens[i];

    if(isOperator(token)){
        std::cout << "3\n"; 
        const std::string o1 = token;

        if(!st.empty()){
            std::cout << "4\n";
            std::string o2 = st.top();

            while(isOperator(o2) && ((isAssociative(o1, LEFT_ASSOC) && cmpPrecedence(o1, o2) == 0) || (cmpPrecedence(o1, o2) < 0))){
                std::cout << "5\n";
                st.pop();
                out.push_back(o2);

                if(!st.empty()){
                    std::cout << " 6\n";    
                    o2 = st.top();
                }
                else{
                    std::cout << "7\n";
                    break;
                }
            }    
        }
        std::cout << "8\n";
        st.push(o1);
    }
    else if(token == "("){
        std::cout << "9\n";
        st.push(token);
    }
    else if(token == ")"){
        std::cout << "10\n";
        std::string topToken = st.top();

        while(topToken != "("){
            std::cout << "11\n"; 
            out.push_back(topToken);
            st.pop();

            if(st.empty() ){
                std::cout<< "12\n";
                break;
            }
            std::cout << "13\n";
            topToken = st.top();
        }
        if(!st.empty()){
            std::cout << "14\n";
            st.pop();
        }
        if(topToken != "("){
            std::cout << "15\n";
            return false;   
        }
    }
    else{
        std:: cout << "16\n";
        out.push_back(token);
    }
}
while(!st.empty()){
    std:: cout << "17\n";
    const std::string stackToken = st.top();

    if(isParentheses(stackToken)){
        std::cout << "18\n";
        return false;
    }
    std::cout << "19\n";
    out.push_back(stackToken);
    st.pop();
}
std::cout << "20\n";
strArray.assign(out.begin(), out.end());
return success; 
}

the segfault is occurring at std::cout << "10\n"; when calling std::string topToken = st.top();

I will give some input/outputs

intput: (8*2) outputs: 1 2 9 2 3 4 8 2 3 4 5 6 8 2 10 11 13 14 2 10 segfault (core dumped)

input: (4/4) output: 1 2 9 2 3 4 8 2 3 4 5 6 8 2 10 11 13 14 2 10 segfault (core dump)

there are a few more tests I ran that I could easily post here but they become very redundant, honestly. If you guys want to see more you need just ask and I will gladly provide more. However I feel like these two should provide enough info...

I know where the segfault is occurring and I have a hunch as to why..so if anyone can confirm to me why exactly the fault is happening that'd be great, and any solutions to the problem would be much appreciated.

P.S: any typos in the code are typos! I copied the code by retyping it since I am coding on a linux OS but I own a pc. With that being said...the code compiles without errors, any misspelled terms are typos!!

thanks again

EDIT: after giving it a few days and coming back to this I ran a few more tests on the code. This time using equations without parentheses.

input:3-9 output:1 2
3 8 2 3 4 5 7 8 17 19 20 segfault (core dump)

input:6/8 output: 1 2 3 8 2 3 4 5 7 8 17 19 20

So I am also getting a segfault when calling strArray.assign( out.begin(), out.end() );


Solution

  • Add the following after the line const std::string token = inputTokens[i];:

    std::cout << "inputTokens[" << i << "]: " << token << std::endl;
    

    I think you'll find that there's a problem with the inputTokens vector or possibly size isn't correct.

    Out of curiosity - why do you pass in size as an argument instead of using inputTokens.size()?