C++ 连续计算器程序中的分段错误
我试着写一个允许链接的计算器。 因此,我的C++ 连续计算器程序中的分段错误,c++,C++,我试着写一个允许链接的计算器。 因此,我的firstSet()函数处理除法和乘法。修改向量,直到secondSet()函数处理加法和减法。我在擦除向量元素的部分出现了一些错误,我怀疑这是发生分段错误的地方 #include <vector> #include <iostream> //Structure: //Vector 'stream' of data objects , where each element is either a num or operator
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;
}
#包括
#包括
//结构:
//数据对象的向量“流”,其中每个元素都是num或运算符
//继承权:
//1.* & /
//2.+ & -
//预期输入:带运算符和分号的间隔整数,用于结束输入语句。
//例如:
//3+2;
//5/6;
结构数据
{
煤焦类型;
int-val;
char op;
数据(字符x,字符y)
:type(x),op(y){}
数据(字符x,整数y):类型(x),值(y){
};
无效第一集(标准::向量&v)///&*
{
内部温度;
对于(自动i=v.begin();i!=v.end()-1;++i)
{
if((*i).type='o'&(*i.op='/'| |(*i.op=='*'))
{
if((*i.op=='/'))
{
温度=(*(i-1)).val/(*(i+1)).val;
}
如果((*i.op='*'))
{
温度=(*(i-1)).val*(*(i+1)).val;
}
(*(i-1)).val=temp;//更改lhs
v、 擦除(i);//删除运算符
v、 删除(i);//删除rhs
}
}
}
无效第二集(标准::向量和v)//+&-
{
内部温度;
对于(自动i=v.begin();i!=v.end();++i)
{
if((*i).type='o'&(*i.op=='+'| |(*i.op=='-'))
{
if((*i.op=='+'))
{
温度=(*(i-1)).val+(*(i+1)).val;
}
如果((*i.op='-'))
{
温度=(*(i-1)).val-(*(i+1)).val;
}
(*(i-1)).val=温度;
v、 删除(i);
v、 删除(i);
}
}
}
int main()
{
std::向量v;
查尔特;
标准:cin>>T;
而(T!=';')
{
如果(T='/'| | T='*'| | T='+'| | T=='-')
{
v、 向后推(数据{'o',T});
}
如果(T>='0'&&T>x;
v、 推回(数据{'n',x});
}
标准:cin>>T;
}
第一组(v);
第二组(v);
std::cout在v.erase(i)
之后使用i
是无效的,因为调用[…]会使迭代器和引用在擦除点或之后失效,包括end()迭代器。[…]
因此,第二个v.erase(i)
是错误的,但是使用++i
继续循环也是无效的,并且会导致未定义的行为
调用erase
后,需要使用有效的迭代器替换i
。例如,使用:
i = v.erase(i);
但是这样做会导致在删除的元素之后跳过每个元素,因此需要更改循环的逻辑
但还有其他无效部分:
(*(i-1)).val=temp;
如果i==v.begin()
(*(i+1)).val如果(i+1)=v.end()
因此,您需要考虑代码的完整逻辑。在v.erase(i)
之后使用i
是无效的,因为调用[…]会使迭代器和引用在擦除点或之后失效,包括end()迭代器。[…]
因此,第二个v.erase(i)
是错误的,但是使用++i
继续循环也是无效的,并且会导致未定义的行为
调用erase
后,需要使用有效的迭代器替换i
。例如,使用:
i = v.erase(i);
但是这样做会导致在删除的元素之后跳过每个元素,因此需要更改循环的逻辑
但还有其他无效部分:
(*(i-1)).val=temp;
如果i==v.begin()
(*(i+1)).val如果(i+1)=v.end()
因此,您需要考虑代码的完整逻辑。为什么要调用v.erase(i)
两次?当i=v.begin()时*(i-1)
的值是多少,当i=v.end()时*(i+1)
的值是多少
如何输入负值?例如9--3
?为什么要调用v.erase(i)
两次?当i=v.begin()时*(i-1)
的值是多少,当i=v.end()时*(i+1)
的值是多少
如何输入负值?例如9--3
?但即使我输入了有效的输入,为什么(*(I-1)).val=temp
无效(代码不会分支到if条件)?@ChiragM我没有检查代码的完整逻辑。如果你只查看void secondSet(std::vector&v)
假设v
的第一个元素的类型为type='o'
和op='+'
,然后将调用(*(i-1)).val=temp
(从代码审查的角度来看,如果认为调用secondSet
的代码可以防止这种情况发生,这并不重要。)但是,即使我输入了有效的输入,为什么(*(I-1)).val=temp
无效(代码不会分支到if条件)?@ChiragM我没有检查代码的完整逻辑。如果您限制自己只查看void secondSet(std::vector&v)
假设v
的第一个元素的类型为type='o'
和op='+'
,然后将调用(*(i-1)).val=temp
(从代码审查的角度来看,如果认为调用secondSet
的代码可以防止这种情况发生,这并不重要。)