I want to know the cause of error If I invert the relational operator in the while statement there is no error and it generates output but in the following code it doesn't gives any output and gives segmentation error while debugging.
#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 segmentation fault in the debugger
h.pop();
}
cout<<h.top()<<" ";
h.pop();
}
return 0;
}
CodePudding user response:
Before you enter the loop, the stack is this:
10 9 8 7 6 5 4 3 2 1
^- top
After 5 iterations of the for loop the stack is this (each iteration pops one element, and because they are all not <6 the while loop does nothing):
5 4 3 2 1
^- top
Now when this stack is fed to
while(h.top() < 6){
h.pop();
}
you will never reach a state where h.top < 6 is false, hence the loop never stops to pop elements from the stack. Eventually you call h.top() on an empty stack and invoke undefined behavior. A segfault is one possible outcome.
You do not see the output of the previous iterations, because there is no way the code does not invoke undefined behavior. Hence, the whole program has undefined behavior. It is not the case that it works well until it crashes. However, in this case flushing the stream (eg via std::endl) will likely produce some output before the crash. It does here https://godbolt.org/z/z4fcvTse4.
When the condition in the while loop is h.top() > 6 this doesn't happen, because the final elements in the stack are all <6 and make the loop stop before the stack is empty. However, the right way would be to check if the stack is empty before calling top just as you do in the for loop:
while(!h.empty() && h.top() < 6){
h.pop();
}
if (!h.empty()) {
cout<<h.top()<<" ";
h.pop();
}
CodePudding user response:
You have to check if the stack is empty or not. Otherwise in the while you are trying to get reference to null.
Try to replace your for cycle with this:
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();
}
