前缀表示法C++,分段错误(堆栈和队列)[解决]
问题描述:
我想弄清楚为什么我得到分段错误,我的猜测是它在我的recusive函数中,它会模拟前缀符号操作。前缀表示法C++,分段错误(堆栈和队列)[解决]
例如
“M + 4 4” 返回: “+米8” 测试期间
我得到分割故障信号:
退出,信号11(SIGSEGV) 相信虽然问题在于我的recusive功能“操作”
string Operate(stack<string> &S, queue<string> &Q)
{
S.push(Q.front());
Q.pop();
std::string::size_type sz;
string result = "";
if (IsOperator(S.top()) == true)
{
S.push(Operate(S, Q));
}
if (Q.empty() == false)
{
S.push(Q.front());
Q.pop();
if (IsOperator(S.top()) == true)
{
S.push(Operate(S, Q));
}
if (S.size() < 3)
return "wrong input";
string arg1 = S.top();
S.pop();
string arg2 = S.top();
S.pop();
string oper = S.top();
S.pop();
if (StringIsDigit(arg1) && StringIsDigit(arg2))
{
int a = stoi(arg1, &sz);
int b = stoi(arg2, &sz);
char o = oper.at(0);
int c = 0;
if (o == '+')
c = b + a;
else if (o == '-')
c = b - a;
else if (o == '*')
c = b * a;
else
return "e";
result = to_string(c);
}
else
result = oper + " " + arg2 + " " + arg1;
}
else
{
result = S.top();
S.pop();
}
return result;
}
//导致分段故障的功能是StringIsDigit
bool StringIsDigit(string arg)
{
bool result = true;
//I only need to check if the first is a '-' char and
//the next char is not ' '.
for (int i = 0; i < arg.size() && result == true; i++)
{
if ((arg.size() != 1) && (arg.at(0) == '-') && (arg.at(1) != ' '))
i++;
else
result = isdigit(arg.at(i));
}
return result;
}
链接到整个程序代码: https://pastebin.com/04pfE55N
答
答案是很简单的,我的错误:段错误是因为许多指出了我的错误,从内存,segmentation fault, wiki阅读。
段错误何时发生? 这是当我的函数StringIsDigit()试图找出超过2个字符的负值是一个整数。在“if语句中,当检查字符串是否确实是一个整数,比如-100”时,我继续读取字符串,直到我到达arg字符串的末尾,但是使用了arg.at(i + 1)。导致代码尝试访问字符串数组之外的内存。感谢Struthersneil找到这个缺陷!
请看看我的老StringIsDigit()找出的一个数值的错误,我做:
bool StringIsDigit(string arg)
{
bool result = true;
for (int i = 0; i < arg.size() && result == true; i++)
{
if ((arg.size() != 1) && (arg.at(0) == '-') && (arg.at(i + 1) != ' '))
i++;
else
result = isdigit(arg.at(i));
}
return result;
}
解决方案 我想,以确保该字符串是因为一个整数解决方案我的算法支持表达式,比如x + 3。这意味着我需要在字符串数组中的每个字符上调用字符串isdigit()。虽然' - '不是一个整数,但' - '显然需要表达一个负整数,所以我做了一个有缺陷的检查,就像你在旧的StringIsDigit()中看到的那样。我没有使用if语句,而是检查了第一个字符' - '和第二个字符是否不是空白'',然后我让isdigit()函数完成剩下的工作。
bool StringIsDigit(string arg)
{
bool result = true;
//I only need to check if the first is a '-' char and
//the next char is not ' '.
for (int i = 0; i < arg.size() && result == true; i++)
{
if ((arg.size() != 1) && (arg.at(0) == '-') && (arg.at(1) != ' '))
i++;
else
result = isdigit(arg.at(i));
}
return result;
}
这听起来像你可能需要学习如何使用调试器来遍历代码。使用一个好的调试器,您可以逐行执行您的程序,并查看它与您期望的偏离的位置。如果你打算做任何编程,这是一个重要的工具。进一步阅读:[如何调试小程序](http://ericlippert.com/2014/03/05/how-to-debug-small-programs/) – NathanOliver
SegFault =发布堆栈跟踪以快速识别问题 – IlBeldus
谢谢为快速反馈!我没有发现我的程序中断的情况。但是我想我可以继续创建测试用例来找出它打破的地方。 –