C :我堆栈顶部发生了什么

C++: What is happening to the top of my stack?

本文关键字:发生了 什么 顶部 堆栈      更新时间:2023-10-16

我正在从事一个分配工作,我必须通过使用两个堆栈来评估一个算术表达式,该算术表达式可能具有比较运算符<=>=(。

例如,输入1 2-3 * 4/5,程序应输出0.6。

但是,每当我在操作后将一个值推回Valuestack时,堆栈顶部的该值在退出doOp()方法后似乎消失或变成垃圾值。我一直在尝试追踪和调试,但我仍然不知道为什么会发生这种情况。

的任何帮助或正确方向的点都将不胜感激。

代码:

#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <string>
#include <stack>
#include <cstring>
using namespace std;
stack<char*> operatorStack;
stack<char*> valueStack;
string input;
void repeatOps(char refOp);
void doOp();
int prec(char refOp);
int main(){
    cout << "Enter expression to be evaluated: ";
    getline(cin, input);
    //Parse the string and perform EvalExp() Algorithm
    char *cString = strdup(input.c_str());
    char *token = strtok(cString, " ");
    while(token !=NULL){
        if(isdigit(token[0])){
            valueStack.push(token);
        }
        else{
            repeatOps(*token);
            operatorStack.push(token);
        }   
            token = strtok(NULL, " ");
    }
    repeatOps('$');
    //print out answer
    cout << valueStack.top() << endl;
}
void repeatOps(char refOp){
    while(valueStack.size() > 1 && prec(refOp) <= prec(*operatorStack.top())){
        //debug print statements REMOVE LATER 
        cout << "Printing top of stack in repeatOps before doOp():  " << valueStack.top() << endl;
        doOp();
    }
}
//return precedence of operator
int prec(char refOp){
    if(refOp == '*' || refOp == '/'){
        return 2;
    }
    else if(refOp == '+' || refOp == '-'){
        return 1;
    }
    //Use $ as a special "end of input" token with lowest precedence
    else if(refOp == '$'){
        return -1;
    }
    // if not any of the operators above, it's comparison operator return 0
    else{
        return 0;
    }
}
void doOp(){
    int x = atoi(valueStack.top());
    valueStack.pop(); 
    int y = atoi(valueStack.top());
    valueStack.pop();
    char * op = operatorStack.top();
    operatorStack.pop();
    double doubleReturnValue;
    bool booleanReturnValue;
    //If it's a comparison operator, push true or false and exit function
    if(strncmp(op, "<=", 2) == 0 || strncmp(op, ">=", 2) == 0){
        char trueResult[] = "true";
        char falseResult[] = "false";
        if(strncmp(op, "<=",2)){
            booleanReturnValue = y <= x;
        }
        else{
            booleanReturnValue = y >= x;
        }
        if(booleanReturnValue){
            valueStack.push(trueResult);
        }
        else{
            valueStack.push(falseResult);
        }
        return;
    }
    //Evaluate arithmetic
    if(*op == '+'){
        doubleReturnValue = y + x;
    }
    else if(*op == '-'){
        doubleReturnValue = y - x;
    }
    else if(*op == '*'){
        doubleReturnValue = y * x;
    }
    else if(*op == '/'){
        doubleReturnValue = y / x;
    }
    //convert the result of the operation to char * for the stack
    char returnChar[10];
    sprintf(returnChar, "%.3f", doubleReturnValue);
    //Debug print statements REMOVE LATER
    cout << "Printing return value in doOp() as char array " << returnChar << endl;
    valueStack.push(returnChar);
    cout << "Printing out top of stack after pushing in doOp(): " << valueStack.top() << endl << endl;
}

如果我没有错,您的问题是您在堆栈上推动本地字符数组。stack<char*>无法保存字符串,它将保存这些字符串的内存地址。当将returnChar推到堆栈上时,仅保存地址,因此,一旦删除了范围并删除了returnChar数组,保存的内存地址点就会置于freed/unused/dused/junk内存中。

解决此问题的最简单方法是使用stack<string>而不是stack<char*>。STL中的字符串将确保复制整个字符串,而不仅仅是局部变量的地址。

此部分在这里无法正常工作:

char *token = strtok(cString, " ");
while(token !=NULL){
    if(isdigit(token[0])){
        valueStack.push(token);
    }

问题在于strtok返回的指针是一个临时指针,该指针将指向下一个呼叫strtok的垃圾。

为了保存结果,您需要在令牌上进行strdup

valueStack.push(strdup(token));

尽管我强烈建议您使用std::string代替堆栈中的指针来避免内存泄漏,避免使用C功能分配内存。

std::stack<std::string> valueStack;
...
valueStack.push(token);