c++ - 连续计算器程序的段错误

标签 c++

我试图编写一个允许链接的计算器。 所以我的 firstSet() 函数处理除法和乘法。修改 vector ,直到 secondSet() 函数处理加法和减法。我在删除 vector 元素的部分有一些错误,我怀疑这是发生段错误的地方。

#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;
}

p.s 任何关于代码可读性和整洁性的评论通常都会有所帮助,因为我希望代码“干净”。

最佳答案

v.erase(i) 之后使用 i 是无效的,因为调用 erase [...]使删除点处或删除点之后的迭代器和引用无效,包括 end() 迭代器。[...]

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

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

i = v.erase(i);

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

但是还有其他部分无效:

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

因此您需要总体上考虑代码的完整逻辑。

关于c++ - 连续计算器程序的段错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57917516/

相关文章:

java - 我可以使用GLFW确定摇杆的品牌和型号吗?

c++ - 有没有办法将枚举自动序列化为 int?

c++ - Arduino 崩溃并在 "random points"处重新启动

c++ - 创建独立控件的好策略 Direct2D

c++ - 在 C++ 中返回一个已知大小的数组?

c++ - OpenCV 图像拼接 - 使用 ExposureCompensator 和 MultiabandBlender 类

c++ - 释放动态内存

c# - 我可以将 IL2CPP(C++ 中间语言)用于非 Unity 应用程序吗?

c++ - WMI 类型转换问题

c++ - 为什么构造函数没有被调用