我想知道错误的原因。如果我反转while语句中的关系运算符,则没有错误生成输出,但在下面的代码中,它没有给出任何输出,并且在调试时给出分段错误。
#include <bits/stdc++.h>
using namespace std;
int main() {
stack<int> h;
h.push(1);
h.push(2);
h.push(3);
h.push(4);
h.push(5);
h.push(6);
h.push(7);
h.push(8);
h.push(9);
h.push(10);
for (int i = 0; i < 10 && !h.empty(); i++) {
while (h.top() < 6) { // This is the point where it shows a segmentation
// fault in the debugger
h.pop();
}
cout << h.top() << " ";
h.pop();
}
return 0;
}
在进入循环之前,堆栈如下:
10 9 8 7 6 5 4 3 2 1
^- top
在for循环的5次迭代之后,堆栈是这样的(每次迭代都弹出一个元素,因为它们都不是<6,while循环什么都不做(:
5 4 3 2 1
^- top
现在,当这个堆栈被馈送到时
while(h.top() < 6){
h.pop();
}
您永远不会达到h.top < 6
是false
的状态,因此循环永远不会停止从堆栈中弹出元素。最终,您在一个空堆栈上调用h.top()
并调用未定义的行为。segfault是一种可能的结果。
您看不到以前迭代的输出,因为代码不可能不调用未定义的行为。因此,整个程序具有未定义的行为。在崩溃之前,它并不是工作得很好。然而,在这种情况下,刷新流(例如通过std::endl
(可能会在崩溃之前产生一些输出。它在这里https://godbolt.org/z/z4fcvTse4.
当while循环中的条件是h.top() > 6
时,这不会发生,因为堆栈中的最后元素都是<6
,并使循环在堆栈为空之前停止。然而,正确的方法是在调用top
之前检查堆栈是否为空,就像在for循环中所做的那样:
while(!h.empty() && h.top() < 6){
h.pop();
}
if (!h.empty()) {
cout<<h.top()<<" ";
h.pop();
}
您必须检查堆栈是否为空。否则,在while
中,您将尝试获取对null
的引用。
尝试用以下内容替换for
周期:
for(int i=0;i<10 && !h.empty();i++) {
while(!h.empty() && h.top() < 6) {
h.pop();
}
if (h.empty())
break;
cout<<h.top()<<" ";
h.pop();
}