休息;导致段错误

break; causing segment fault

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

我尝试删除 break 程序运行正常但打印错误答案,因为需要 break 才能打印正确的输出。这种段错误的原因是什么?中断不访问任何内存 unit.right?

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

崩溃是因为在平衡输入的情况下你的循环没有终止。所以你最终会从空堆栈中弹出一些东西。

您应该使用 do while 循环编写此代码

do
{
    ...
    if (c == ')' && comp != '(')
        break;
    ...
}
while (!s.empty());
if (s.empty())
   cout << "balanced\n";
else
   cout << "not balanced\n";

虽然即使那样你也需要同步你的输入。也许您应该读取整个输入(也许每行一个字符串?),然后处理输入字符串。在那种情况下,您可以用 for 循环替换 do while 循环,例如for (char c : input)

因此,first some background information on std::stack 稍后将变得相关:

The programming-by-contract style would be that having a non-empty stack is a precondition of calling pop, and that calling a method without meeting its preconditions has an undefined outcome.

请注意,虽然我找不到来源说当堆栈中有 0 个元素时 s.top() 是错误的,但出于同样的原因,我假设它也是错误的。

为什么这很重要?嗯,,包括段错误。把它记在脑后。

所以,这段代码就在这里:

comp=s.top();

如果您 运行 遇到 s 为空的情况,而您有其他内容来自 std::cin,会发生什么情况?例如,如果你在括号的末尾有一个额外的 ) 会怎样:

()()) // <-- extra )

()s 抵消了,但是 ) 仍然存在。因此,当您尝试引用顶部时,那里什么也没有。这可能是导致崩溃的原因。

在尝试引用顶部之前,您需要检查此行以确保 s 不为空:

if(!s.empty()) {
    comp=s.top();
}

你也应该在 pop() 前后这样做:

if(c==')' && comp=='(' && !s.empty())
           s.pop();

或者类似的东西。您的逻辑可能需要一些修改,但希望这能给您带来灵感。