为什么我的程序使用std :: vector创建一个堆栈崩溃? [英] Why does my program that creates a stack using std::vector crash?

查看:177
本文介绍了为什么我的程序使用std :: vector创建一个堆栈崩溃?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我为我的数据结构类创建了自己的堆栈。对于我们的赋值,我们使用赋值将实时中缀方程转换为后缀方程。

我认为我的程序:

输入了

如果是数字或数字(操作数)

打印出来

确定输入是否是运算符(+, - ,/,*)

添加到堆栈或打印输出,取决于堆栈的优先级

I am creating my own stack for my data structures class. For our assignment we are using the assignment to convert a real-time infix equation into a postfix equation.
I thought my program:
took input
determines if it was digit or number(operand)
prints it out
determines if input is operator (+,-,/,*)
adds to stack or prints out, depending on stack precedence

而是打印输出的操作数,但我输入一个运算符时会出现这个错误

Instead it prints out the operands as expect, but I get this error when I enter an operator

>.../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; 

我的代码很长,我知道,但我很感激帮助。

My code is very length, I know, but I appreciate help. Especially any times for efficency or future coding.

再次感谢

Dr. Zemoudeh,这是你的学生Macaire

P.S. Dr. Zemoudeh, this is your student Macaire

推荐答案

我会扩展Rup的答案,回答你没有问的问题,但更重要的是:我如何知道我的程序崩溃的位置?

I'll expand on Rup's answer to answer the question you didn't ask, but is more important: How can I find out where my program is crashing?

一种方法是将 std :: cout printf 语句。在每个函数的开头放一个语句,function x enter,最后说function x exit。运行你的程序,当它崩溃,你会看到它是什么函数。在这一点上,你可以添加行打印每个变量的内容,以找出什么错误。

One way is to put std::cout or printf statements throughout your program. Put a statement at the beginning of every function saying, "function x enter" and at the end saying, "function x exit". Run your program and when it crashes, you'll see what function it's in. At that point, you can add lines to print the contents of each variable to find out what's going wrong.

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

Another way is to use a debugger, like gdb.

-g 切换以启用调试信息。

First, compile your program with the -g switch to enable debugging information.

linux@linux-ubuntu:~/t$ g++ prog.cpp -o prog -g

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

Next, tell the debugger gdb to run your program.

linux@linux-ubuntu:~/t$ gdb ./prog

在gdb提示符处,键入 run 启动你的程序。我输入 4 *(3 + 2),程序在prog.cpp:7 下崩溃了 return Well.back();

At the gdb prompt, type run to start your program. I entered 4*(3+2) and the program crashed at prog.cpp:7, which is the line 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();  

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

For more complex programs, you'll often need a list of all the functions that are currently being called. You can get that information with bt, short for "backtrace". In the following backtrace, you see that the function main (#1) is calling function DishWell::ReturnEnd (#0). #0 is the current function because functions form a stack, where the current function is the top of the stack (offset 0 is the top).

(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) 

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

With only these 2 commands (run, bt), you've solved 80% of the problem: finding where your program has crashed. If you stopped reading here, you should be able to solve the problem by adding print statements or asserts to see what the state of Well is and why back() is crashing your program. But let's use gdb some more...

您可以键入 list 在不离开调试器的情况下查看该行周围的源代码。

You can type list to see the source code around that line for more context without leaving the debugger.

(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) 

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

gdb can print variables and simple expressions. Printing the value of Well here is not too helpful for the novice, because it's a complex data structure and not a simple variable. But we can tell gdb to call a method on that variable...

(gdb) print Well.size()
$2 = 0
(gdb) print Well.empty()
$3 = true


$ b b

Ah ha, Well 是空的,你已经调用 back()。当我们查看 std :: vector的一些良好文档 ,我们看到您调用未定义的行为,在这种情况下是程序崩溃。

Ah ha, Well is empty, and you've called back() on it. When we look at some good documentation for std::vector, we see that you invoke undefined behavior, which in this case is a program crash.

现在看看您的程序,为什么很好是空的,当你的程序不希望它是空的。如果你喜欢 gdb ,请阅读一些教程,了解如何设置断点或单步。

Now look through your program and try to figure out why Well was empty when your program wasn't expecting it to be empty. If you like gdb, read some tutorials on it and learn how to do things like set breakpoints, or single step.

这篇关于为什么我的程序使用std :: vector创建一个堆栈崩溃?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆