打破;导致段故障

时间:2019-08-07 05:18:12

标签: c++ stack break

我正在使用堆栈进行括号检查。包含 break; 语句的 if else 语句之一导致段错误。

我尝试删除中断程序运行正常,但打印错误的答案,因为需要中断才能打印正确的输出。这种网段故障的​​原因是什么?中断无法访问任何存储单元。对吗?

Questions link

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

2 个答案:

答案 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();

或者类似的东西。您的逻辑可能需要重新设计,但希望可以为您提供思路。