繁体   English   中英

连续计算器程序上的分段错误

[英]Segmentation fault on continuous calculator program

我试图写一个允许链接的计算器。 因此,我的firstSet()函数处理除法运算和。 修改向量,直到secondSet()函数处理加法和减法。我在擦除向量元素的部分出现了一些错误,这是我怀疑发生分段错误的地方。

#include <vector>
#include <iostream>

//Structure:
//Vector 'stream' of data objects , where each element is either a num or operator
//Heirarchy:
//1.* & /
//2.+ & -
//expected input : Spaced integers with operators and a semicolon to end the input statement.
//for ex:
//3+2;
//5/6;
struct Data
{
    char type;
    int val;
    char op;
    Data(char x , char y)
        : type(x) , op(y){} 
    Data(char x , int y) : type(x) , val(y){} 
};
void firstSet(std::vector<Data> & v)    // / & *
{
    int temp;
    for (auto i = v.begin(); i != v.end()-1 ; ++i)
    {
        if ((*i).type == 'o' && ((*i).op == '/' || (*i).op == '*'))
        {
            if ((*i).op == '/')
            {
                temp =  (*(i-1)).val / (*(i+1)).val;
            }
            if ((*i).op == '*')
            {
                temp = (*(i-1)).val * (*(i+1)).val;
            }
            (*(i-1)).val = temp; // change lhs
            v.erase(i);         //delete operator
            v.erase(i);         //delete rhs

        }
    }
}
void secondSet(std::vector<Data> & v) // + & - 
{

    int temp;
    for (auto i = v.begin(); i != v.end() ; ++i)
    {
        if ((*i).type == 'o' && ((*i).op == '+' || (*i).op == '-') )
        {
            if ((*i).op == '+')
            {
                temp =  (*(i-1)).val + (*(i+1)).val;
            }
            if ((*i).op == '-')
            {
                temp = (*(i-1)).val - (*(i+1)).val;
            }

            (*(i-1)).val = temp;
            v.erase(i);
            v.erase(i);


        }
    }
}

int main()
{
    std::vector<Data> v;
    char T;
    std::cin >>T;
    while (T != ';')
    {
        if (T == '/' || T == '*' || T == '+' || T == '-')
        {
            v.push_back(Data{'o' , T});
        }
        if (T >= '0' && T <= '9')
        {
            std::cin.putback(T);
            int x;
            std::cin >> x;
            v.push_back(Data{'n' , x});
        }

        std::cin >> T;
    }
    firstSet(v);
    secondSet(v);
    std::cout << v[0].val;
}

ps关于代码可读性和整洁性的任何注释一般都会有所帮助,因为我希望代码“干净”。

v.erase(i)之后使用i是无效的,因为调用橡皮擦 [...]invalidates iterators and references at or after the point of the erase, including the end() iterator.[...]

因此第二个v.erase(i)是错误的,但是使用++i继续循环也是无效的,并且会导致不确定的行为。

调用erase后,您需要用有效的迭代器替换i 例如使用:

i = v.erase(i);

但是这样做会导致在擦除一个元素之后跳过每个元素,因此您需要更改循环逻辑。

但是还有其他无效的部分:

  • (*(i-1)).val = temp; 如果i==v.begin()将无效
  • (*(i+1)).val如果(i+1)==v.end()将无效

因此,您通常需要考虑代码的完整逻辑。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM