c++ - 将中缀转换为后缀并得到段错误核心转储错误

标签 c++ segmentation-fault

我已经通过 valgrind 和 gdb 运行了我的程序,每次我都因为 T tempData = top -> data; 行而收到段错误核心转储错误在我的 Stack 类中,但我不知道为什么。帮助!!!!

这是我的代码。首先stack.h:

/*
* Stack.h
*
*  Created on: Feb 4, 2014
*      Author: csuser
*/

#ifndef STACK_H_
#define STACK_H_
#include <cstdlib>
#include <iostream>
#include "StackNode.h"
using namespace std;
template <class T>
class Stack
{
private:
    StackNode<T> *top;

public:

    Stack()
    {
        top = NULL;
    }
    void push(T c)
    {
        //allocate a stack node
        StackNode<T> *stack1 = new StackNode<T>(c);

        //make the top of the stack point to the new node, and if there was previously
        //something in the stack, the old top's next node pointer points to the new top's
        //pointer
        stack1->next = top; //makes the new StackNode pointer point the old top of the stack
        top = stack1; //makes the new StackNode pointer the top of the stack
    }

    T pop() //T because pop returns whatever T is
    {
        //saves the old top of the stack so when you reset top
        //you don't lose the top of the stack
        StackNode<T> *temp = top;
        cout << "1 2 3" << endl;
        ***T tempData = top->data; ***
        cout << "4 5 6" << endl;
        top = top->next;
        delete temp;

        //returns the data from the StackNode that was popped
        //i.e., allows you to see the operand
        return tempData;
    }

    void printStack()
    {
        //Creates a pointer that points to the top of the stack
        //So you can traverse through the stack by moving the pointer
        StackNode<T> *ptr = top;

        while (ptr != NULL)
        {
            cout << ptr->data << endl;
            ptr = ptr->next; //Advances the pointer
        }
    }

    StackNode<T>* getTop()
    {
        return top;
    }

    /*
    T peek()
    {
    return top -> getData();
    }
    */
};
#endif /* STACK_H_ */
/////////////This ends my first header file////////////////////////////

这是我的 stacknode.h:

////////This begins my second and last header file////////////////
/*
* StackNode.h
*
*  Created on: Feb 4, 2014
*      Author: csuser
*/

#ifndef STACKNODE_H_
#define STACKNODE_H_
#include "Stack.h"
template <class T>
class Stack;

template <class T>
class StackNode
{
private:
    T data;
    StackNode<T> *next;

public:
    friend class Stack<T>; //makes the Stack class a friend to the StackNode class

    //StackNode Constructor function
    StackNode(T Data)
    {
        data = Data;
        next = NULL;
    }

    T getData()
    {
        return data;
    }

    StackNode* getNext()
    {
        return next;
    }


};
#endif /* STACKNODE_H_ */
//////This ends my second and last header file///////

...和我的 main.cpp:

///////////This begins my main.cpp/////////////////////

/*
* Main.cpp
*
*  Created on: Feb 4, 2014
*      Author: csuser
*/
#include "Stack.h"
#include "StackNode.h"
#include <iostream>
#include <cstdlib>
#include <fstream>
#include <string>
using namespace std;
void convert(string, string);
double evaluate(string);
int precedence(char a);

int main()
{
    //double answer;
    string fileName;
    cout << "Please enter a file name that has infix expressions" << endl;
    cin >> fileName;

    string infix;
    ifstream infile;
    infile.open(fileName.c_str());

    if (infile.fail())
    {
        cout << "couldn't open text file..." << endl;
    }

    while (!infile.eof())
    {
        getline(infile, infix);
        cout << "reading in the data..." << endl;
        //cout << infix << endl;
        string postFix(infix); //makes a string called postFix with the same length as infix

        cout << "right before convert function call.." << endl;
        convert(infix, postFix);
        cout << "right after convert function call..." << endl;
        //answer = evaluate(postFix);
        //cout << answer << endl;
    }

    infile.close();
}

//Evaluate function
double evaluate(string postFix)
{
    Stack<double> stk;
    double left;
    double right;
    double result;

    for (int i = 0; i<(int) postFix.length(); i++)
    {
        if (isdigit(postFix[i]))
        {
            stk.push(postFix[i]);
        }
        else if (postFix[i] == '*')
        {
            //pops one of the operands and puts it on the right hand side of a x + y operation
            right = stk.pop();

            //pops of of the operands and puts in on the left hand side of a x + y operation
            left = stk.pop();
            result = right * left;
            stk.push(result);
        }

        else if (postFix[i] == '/')
        {
            //pops one of the operands and puts it on the right hand side of a x + y operation
            right = stk.pop();

            //pops of of the operands and puts in on the left hand side of a x + y operation
            left = stk.pop();
            result = left / right;
            stk.push(result);
        }

        else if (postFix[i] == '+')
        {
            //pops one of the operands and puts it on the right hand side of a x + y operation
            right = stk.pop();

            //pops of of the operands and puts in on the left hand side of a x + y operation
            left = stk.pop();
            result = left + right;
            stk.push(result);
        }

        else if (postFix[i] == '-')
        {
            //pops one of the operands and puts it on the right hand side of a x + y operation
            right = stk.pop();

            //pops one of the operands and puts in on the left hand    side of a x + y operation
            left = stk.pop();

            result = left - right;

            stk.push(result);
        }
    }
    return stk.getTop()->getData();
}

//Convert function
void convert(string infix, string postFix)
{

    Stack<char> stk;
    char Data;
    int j = 0;
    char z;


    //Use for loop to walk along the string
    //the (int) in front of infix.length casts infix.length as an int
    //because i is an int and string.length returns an unsigned int and we
    //need the types to match
    //cout << "Right before the for loop in convert function" << endl;
    for (int i = 0; i<(int) infix.length(); i++)
    {
        //Case 1: an operand is found and is printed immediately
        cout << "right before the first case in convert function" << endl;
        if (isdigit(infix[i]))
        {
            //cout << "inside case one in convert" << endl;
            postFix[j] = infix[i];
            j++;
        }
        //cout << "right after case one in convert" << endl;
        //Case 2: if a right parenthesis is found, then the stack is continuously popped
        //until a left parenthesis is found
        else if (infix[i] == ')')
        {
            //cout << "Inside case two in convert function" << endl;
            while ((Data = stk.pop()) != '(')
            {
                //cout << "Data = " << Data << endl;
                postFix[j] = Data;
                j++;
            }
        }

        //Case 3: if we see any other symbol besides a right parenthesis, excluding operands,
        //we continuously pop the stack until we find an operator with lower precedence
        else if ((infix[i] == '(') || (infix[i] == '*') || (infix[i] == '/') || (infix[i] == '+') || infix[i] == '-')
        {
            while (precedence(z = stk.pop()) >= precedence(infix[i]))
            {
                //Data = stk.pop();
                stk.push(postFix[j] = z);
                j++;
            }
        }
    }
    //prints out the rest of the stack
    while (stk.getTop() != NULL)
    {
        postFix[j] = stk.pop();
        j++;
    }
}

//Precedence function
int precedence(char a)
{
    if ((a == '(') || (a == ')'))
    {
        return 6;
    }

    else if ((a == '*') || (a == '/'))
    {
        return 5;
    }

    else if ((a == '-') || (a == '+'))
    {
        return 4;
    }

    else
    {
        return 0;
    }
}

最佳答案

您正在取消引用 null。你的堆栈是空的!不要问我为什么。而是调试我们的 convert 函数。

我没有仔细查看您使用堆栈的代码,但您的 StackNode 和 Stack 实现没问题(除了空堆栈处理)。

关于c++ - 将中缀转换为后缀并得到段错误核心转储错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21719097/

相关文章:

c++ - 标识符 calcHist() 在 C++ 的 OpenCV 中未定义

c++ - 考虑 。 (点)当应用于应该是运行时多态的东西时

c - 实现 C 程序排序时出现段错误

c++ - MPI-2 中的段错误

c - 复制结构时出现段错误

c++ - 结构的多维数组 - 段错误

c++需要有关如何使用回调函数的帮助

c++ - 在另一个线程上向 QObject 发出信号的正确方法?

c++ - SubclassWindow() 函数断言

c - C语言使用BFS寻找节点之间的路径