为什么我的程序使用std :: vector创建堆栈崩溃?

Mal*_*ken 2 c++ stack

我正在为我的数据结构类创建自己的堆栈.对于我们的任务,我们使用赋值将实时中缀方程转换为后缀方程.
我认为我的程序:
输入
确定它是否为数字或数字(操作数)
打印输出
确定输入是否为运算符(+, - ,/,*)
添加到堆栈或打印输出,具体取决于堆栈优先级

相反,它会按预期打印出操作数,但是当我进入运算符时出现此错误

>.../dorun.sh line 33: 4136 Segmentation fault     <core dumped> sh "$<SHFILE>"


#include <vector>
using namespace std;

class DishWell{  
public:  
    char ReturnEnd(){  
        return Well.back();  
    }  
    void Push(char x){  
        Well.push_back(x);  
    }  
    void Pop(){  
        Well.pop_back();  
    }  
    bool IsEmpty(){  
        return Well.empty();  
    }  
private:  
    vector<char> Well;  
};   
#include <iostream>  
bool Precidence(char Input, char Stack){  
    int InputPrecidence,StackPrecidence;  
    switch (Input){  
        case '*':  
            InputPrecidence = 4;  
            break;
        case '/':
            InputPrecidence = 4;  
            break;  
        case '+':  
            InputPrecidence = 3;  
            break;  
        case '-':  
            InputPrecidence = 3;  
            break;  
        case '(':  
            InputPrecidence = 2;  
            break;  
        default:  
            InputPrecidence = 0;  
    }  
    switch (Stack){  
        case '*':  
            StackPrecidence = 4;  
            break;  
        case '/':  
            StackPrecidence = 4;  
            break;  
        case '+':  
            StackPrecidence = 3;  
            break;  
        case '-':  
            StackPrecidence = 3;  
            break;  
        case '(':  
            StackPrecidence = 2;  
            break;  
        default:  
            StackPrecidence = 0;  
    }  
    if(InputPrecidence>StackPrecidence) return true;  
    else return false;  
}  
int main(int argc, char** argv) {  
    DishWell DishTray;  
    char Input;  
    bool InputFlag;  
    InputFlag = true;  
    while(InputFlag){  
        cin>>Input;  
        if((((Input>='a'&&Input<='z')||(Input>='A'&&Input<='Z'))|| (Input>='0'&&Input<='9')))//If Digit or Number  
            cout<<Input;  
        if((Input=='*'||Input=='/'||Input=='+'||Input=='-')){//if operand  
            if(Precidence(Input,DishTray.ReturnEnd()))  
                DishTray.Push(Input);  
            else if(!Precidence(Input,DishTray.ReturnEnd()))  
                cout<<Input;  
        }  
        else if(!((((Input>='a'&&Input<='z')||(Input>='A'&&Input<='Z'))||    (Input>='0'&&Input<='9')))||((Input=='*'||Input=='/'||Input=='+'||Input=='-')))//if not digit/numer or operand  
            InputFlag = false;  
    }  
    while(!DishTray.IsEmpty()){  
        cout<<DishTray.ReturnEnd();  
        DishTray.Pop();  
    }  
    return 0; 
Run Code Online (Sandbox Code Playgroud)

我知道,我的代码很长,但我很感激帮助.特别是效率或未来编码的任何时候.

再次感谢

PS Zemoudeh博士,这是你的学生Macaire

ind*_*div 6

我将扩展Rup的答案来回答你没有问过的问题,但更重要的是: 我怎样才能找到我的程序崩溃的位置?

一种方法是在整个程序中放置std::coutprintf声明.在每个函数的开头写一个声明,"function x enter",最后说"function x exit".运行你的程序,当它崩溃时,你会看到它所处的功能.此时,你可以添加行来打印每个变量的内容,以找出出错的地方.

另一种方法是使用调试器,如gdb.

首先,使用-g开关编译程序以启用调试信息.

linux@linux-ubuntu:~/t$ g++ prog.cpp -o prog -g
Run Code Online (Sandbox Code Playgroud)

接下来,告诉调试器gdb运行您的程序.

linux@linux-ubuntu:~/t$ gdb ./prog
Run Code Online (Sandbox Code Playgroud)

在gdb提示符下,键入run以启动您的程序.我进去4*(3+2)了,程序崩溃了at prog.cpp:7,就行了return Well.back();.

(gdb) run
Starting program: /home/linux/t/prog 
4*(3+2)
4
Program received signal SIGSEGV, Segmentation fault.
0x08048d0b in DishWell::ReturnEnd (this=0xbffff460) at prog.cpp:7
7           return Well.back();  
Run Code Online (Sandbox Code Playgroud)

对于更复杂的程序,您通常需要列出当前正在调用的所有函数.您可以使用bt"回溯"的缩写获取该信息.在下面的回溯中,您会看到函数main(#1)正在调用函数DishWell::ReturnEnd(#0).#0是当前函数,因为函数形成堆栈,其中当前函数是堆栈的顶部(偏移量0是顶部).

(gdb) bt
#0  0x08048d0b in DishWell::ReturnEnd (this=0xbffff460) at prog.cpp:7
#1  0x08048b35 in main (argc=1, argv=0xbffff534) at prog.cpp:75
(gdb) 
Run Code Online (Sandbox Code Playgroud)

只有这两个命令(run,bt),您已经解决了80%的问题:找到程序崩溃的位置.如果您在这里停止阅读,您应该能够通过添加print语句或断言来解决问题,以查看状态Well是什么以及为什么back()崩溃您的程序.但是让我们再使用gdb一些......

您可以键入list以查看该行周围的源代码,以获得更多上下文,而无需离开调试器.

(gdb) list
2   using namespace std;
3   
4   class DishWell{  
5   public:  
6       char ReturnEnd(){  
7           return Well.back();  
8       }  
9       void Push(char x){  
10          Well.push_back(x);  
11      }  
(gdb) 
Run Code Online (Sandbox Code Playgroud)

gdb可以打印变量和简单表达式.打印Well这里的值对新手来说没什么用处,因为它是一个复杂的数据结构,而不是一个简单的变量.但我们可以告诉gdb在该变量上调用一个方法......

(gdb) print Well.size()
$2 = 0
(gdb) print Well.empty()
$3 = true
Run Code Online (Sandbox Code Playgroud)

啊哈,Well是空的,你已经打电话back()了.当我们查看一些好的文档std::vector,我们会看到您调用未定义的行为,在这种情况下是程序崩溃.

现在看看你的程序,并尝试找出Well当你的程序不期望它是空的时候为什么是空的.如果您愿意gdb,可以阅读一些教程并学习如何设置断点或单步.