我正在使用堆栈进行括号检查。包含 break; 语句的 if else 语句之一导致段错误。
我尝试删除中断程序运行正常,但打印错误的答案,因为需要中断才能打印正确的输出。这种网段故障的原因是什么?中断无法访问任何存储单元。对吗?
#include <iostream>
#include<stack>
using namespace std;
int main() {
//code
int n;
char c,comp;
cin>>n;
while(n--)
{
stack<char>s;
while(cin>>c)
{
if(c=='(' || c=='{'|| c=='[')
s.push(c);
else
{
comp=s.top();
if(c==')' && comp=='(')
s.pop();
else if(c==')' && comp!='(')
{
cout<<"not balanced"<<endl;
break; //this one, if i remove this no SIGSEGV
}
if(c=='}' && comp=='{')
s.pop();
else if(c=='}' && comp!='{')
{
cout<<"not balanced"<<endl;
break;
}
if(c==']' && comp=='[')
s.pop();
else if(c==']' && comp!='[')
{
cout<<"not balanced"<<endl;
break;
}
}
}
if(s.empty())
cout<<"balanced"<<endl;
}
return 0;
}
答案 0 :(得分:1)
之所以引起崩溃,是因为在平衡输入的情况下,您没有终止到循环的原因。因此,您将最终从空堆栈中弹出一些东西。
您应该使用do while循环对此进行编码
do
{
...
if (c == ')' && comp != '(')
break;
...
}
while (!s.empty());
if (s.empty())
cout << "balanced\n";
else
cout << "not balanced\n";
尽管如此,您仍然需要同步输入。也许您应该阅读整个输入(也许每行一个字符串?),然后对输入字符串进行处理。在这种情况下,您可以将for while循环替换为for循环,例如for (char c : input)
答案 1 :(得分:1)
因此,first some background information on std::stack
将在以后变得相关:
按合同编程的样式将是具有非空堆栈是调用pop的先决条件,而不满足其先决条件的方法调用会产生 undefined (未定义)结果。
请注意,当堆栈中有0个元素时,虽然找不到s.top()
不好的消息源,但我还是假设出于同样的原因它也是不好的消息。
为什么那么重要?好吧,undefined behavior can do anything,包括段错误。只要把它放在脑后。
因此,此代码就在这里:
comp=s.top();
如果您遇到s
为空的情况,而您又从std::cin
进来了什么,该怎么办?例如,如果您在圆括号的末尾加上一个),该怎么办:
()()) // <-- extra )
()
取消了,但是)仍然存在。因此,当您尝试引用顶部时,什么也没有。这可能是导致崩溃的原因。
您需要对此行进行检查,以确保s
不为空,然后再尝试引用顶部:
if(!s.empty()) {
comp=s.top();
}
您也可能应该在pop()
周围这样做:
if(c==')' && comp=='(' && !s.empty())
s.pop();
或者类似的东西。您的逻辑可能需要重新设计,但希望可以为您提供思路。