infinite loop in stack implementation c++ - c++

this is my first data structure program. I am implementing a simple stack using array with push, pop and initialize functions. I am getting an infinite loop as the output. Could you please tell me why is this so?
#include<iostream>
using namespace std;
# define SIZE 6
class stack{
public:
void init();
void push(int i);
int pop();
int top;
int stck[SIZE];//bydefault private
};
void stack::init()
{
top=0;
return;
}
void stack::push(int i)
{
if(top==SIZE)
{
cout<<"stack is full";
return;
}
else
{
top=top+1;
stck[top]= i;
return;
}
}
int stack::pop()
{
if(top==0)
{
cout<<"stack is empty. \n";
return 0;
}
else
{
top = top-1;
return(stck[top-1]);
}
}
int main()
{
stack stack1;
stack1.init();
int a;
int m;
while(a!=4)
{
cout<<"1. push 2. pop 3.display 4.exit .\n";
cin>>a;
if(a==1){
cout<< "enter value";
cin>>m;
stack1.push(m);
}
if(a==2)
{
cout<<"popped"<< stack1.pop();
}
if(a==3)
{
for(int k=0; k<=stack1.top;k++)
{
cout<<stack1.stck[k];
}
}
}
}

You never initialize a, so your program has undefined behaviour. Specifically, the while (a != 4) line performs an lvalue-to-rvalue conversion of a while its value is indeterminate, which the C++ standard explicitly states as undefined behaviour in section 4.1.
However, I doubt this is causing the issue at hand. In practice, unless the optimizer just optimized all your code out, your program should usually behave as expected; it's only when a == 4 on the first loop that you have problems. This doesn't make the code acceptable, but there's probably more to it.
I suspect the problem is that you use top to represent one past the number of elements. When you have zero elements, you point to the first; when you have one, you point to the second, etc. This means you're pointing to the first unused element.
However, in both your push and pop functions, you change top first and only then access the stack, but acting as if you didn't change it:
top = top + 1;
stck[top] = i;
When your stack is empty, this will set top to 1 and then access stck[1]. Meanwhile, stck[0] is left unset. When popping, you have the opposite:
top = top - 1;
return stck[top-1];
This sets top back to 0, but returns stck[-1], which is out of bounds.
I suspect that if you push SIZE values onto the stack, you will end up overwriting unrelated memory, which could cause all kinds of trouble. I still don't see how an infinite loop will follow, but given the behaviour is undefined, it is certainly a possible result.
(The alternative is that you at some point enter something other than a number. Seeing as you never check whether your input succeeded, if a != 4 and you enter something invalid, all further reads will fail, and a will remain unequal to 4. You could fix this by making changing your while to be
while (a != 4 && std::cin)
In that case, if you enter something invalid and std::cin goes into a non-good state, your loop (and thus program) will end.)

You only have a single loop, terminated based on user input.
If cin>>a fails, a will have whatever value it started with (undefined in your code), and you will loop on that unchanging value.
Typical ways for the input call to fail include
pressing control+D (on a *nix system)
pressing control+Z (on a Windows system)
redirected input from a pipe or file which is exhausted
There may be other causes of failed input as well.

Related

Memory-leak when rewriting data (C++)

Ive problem with my code (C++)causing memory leak ( i belive). Basically i want it to do the following: take data from user untill he writes "stop" and make heap out of that data. I guess that I'm missing a removal of booked memory at some point but i dont know how to fix it. Also the code seems to be working in code::blocks but it crashes in Dev C++.
cout<<"Enter data to heap if u wanna stop write stop."<<endl;
int *w1=new int[1];
int kek=0;
while(true)
{
cin>>*(w1);
if (!cin)
{ /// the "stop"" thingy
w1=w1-kek;
cout<<"heap: "<<endl;
for (int i=0;i<kek;i++)
{
cout<<" "<<*w1<<" ";
w1++;
}
break;
}
int *w2=new int[2+kek];
w1=w1-kek;
for(int t=0;t<kek+1;t++) ///rewriting data to new chunks of memory
{
*w2=*w1;
w2++;
w1++;
}
delete[]w1; ///releasing old ones ( i think something is wrong here)
w1=w2;
kek++;
w1=w1-kek-1;
int kekkeeper=kek;
for(int l=log(kek)/log(2);l>0;l--) /// heapnig things up
{
if(*(w1+kekkeeper/2)>*(w1+kekkeeper)) swap (*(w1+kekkeeper/2),*(w1+kekkeeper));
else break;
kekkeeper=kekkeeper/2;
}
w1=w1+kek+1;
w2=NULL;
delete[]w2;
}
look at the last tow lines
you set w2 to NULL before your delete it
you changed both pointers w1 and w2 in the following loop
for(int t=0;t<kek+1;t++) {
*w2=*w1;
w2++;
w1++;
}
so you must reset this modification for each pointer before deleting it.
the reseting instruction for w1 can look like this
w1=w1-(kek+1);
delete[]w1;
and for w2 like this
w2=w2-kek;
delete[]w2;
finally you must move the allocation of w1 into the while loop.

1D Peak, on execution says an error has caused the code to be stop working

I am trying to find the 1D peak through Divide and Conquer technique in this particular question,
my program even though it runs,
but at the time of giving the final output it says that there has been some problem with the execution,
I have got the answer from a different method, but I would like to know where am I at fault here.
#include<iostream>
using namespace std;
int a[8];
class pg1
{
public:
int func(int n)
{
if(a[n] <= a[n+1])
{
func(n++);
}
else if(a[n] <=a [n-1])
{
func(n--);
}
else
{
return n;
}
}
};
int main()
{
pg1 ob;
for(int i=0;i<8;i++)
{
cin >> a[i];
}
int x = ob.func(4);
cout << endl << x;
return 0;
}
Input-
5
6
8
5
4
3
6
4
Errors are-
1D Peak.exe has stopped working.
A problem caused the program to stop working correctly.Windows will close the program and notify you aif a solution is available.
End Result-
Process Exited with return value 3221225725
Don't use postincrement and similar in function calls.
Here's the problem condensed down to a really simple piece of code
#include <iostream>
int test(int n){
if(n == 1){
std::cout << "Function called!";
return test(n++);
}else{
return 0;
}
}
int main() {
test(1);
return 0;
}
Before you run this, ask yourself what you expect to happen here. Did it do what you thought?
When you run this you'll see that the code doesn't terminate properly. The output shows the function gets called infinitely many times, eventually the stack runs out of space and the program crashes.
You can see this code in action here: http://ideone.com/QL0jCP
In your program you have the same problem:
int func(int n)// say n = 4
{
if(a[n] <= a[n+1])//say this is true
{
func(n++); //this calls func(4) THEN increments n afterwards
}
This calls func with the same value over and over.
The solution is to not use postincrement or postdecrement in your function calls. These create hard to diagnose bugs as you have seen in this question. Just a simple func(n+1) is all you need. If you needed to use the variable later then just create an explicit variable to do that, it's much cleaner coding style (as this problem you ran into here shows).
After you fix this you'll need to fix your array bounds checking.
if(a[n] <= a[n+1])
If n is the last spot in the array you suddenly are trying to access one place past the end of the array, if you are lucky you get a segfault and a crash, if you are unlucky you get some bug that messes up your system that is hard to find. You want to check the values are valid.

C++ Function will not execute more than once

I've tried looking around but I can't find anything about this anywhere.
I'm writing a custom array class with a "push" function to add a value to the array.
It seems to work perfectly fine but won't execute more than once.
Take the main method below for example:
int main()
{
Array<int> test(4,5);
test.push(4);
test.writeOrdered("Output.txt");
return 0;
}
This will put the int value 4 into the array at the first available position and execute the writeOrdered function.
The following main method, on the other hand:
int main()
{
Array<int> test(4,5);
test.push(4);
test.push(5);
test.writeOrdered("Output.txt");
return 0;
}
This will put the number 4 into the array at the first available point as above and then stop. It won't execute any further lines of code.
Here's the push function for reference:
void push(Datatype p_item)
{
bool inserted = false;
int i = 0;
while (inserted == false)
{
if (m_array[i] < 0)
{
m_array[i] = p_item;
i++;
inserted = true;
cout << p_item << " saved to array" << endl;
system("pause");
}
}
}
You have an infinite loop. After the first insert m_array[0] >= 0 and i never grows. You would have found it out, had you debugged the code somehow.
Basically I don't understand your push function but the way it is, after you insert a non-negative value into the first position any further call to your push function results in a tight loop.
I imagine that you want the i++ outside the if statement.
Without seeing the full implementation of the Array class I would guess that the array m_array contains negative numbers by default. This will allow the first call to the push method to succeed. The next call to the method contains a value of 4 at index 0 and will be stuck in an infinite loop because inserted will never be set to true nor will the value of i be incremented.

Null pointers to classes

I was trying to validate pointers in an array so I didn't cause any memory errors,
and this method:
for(int i=0;i<array_size;i++) {
if (array[i]!=NULL)
array[i]->stuff();
}
}
has worked in the past.
Now, I have to do the same thing, except do it all in order based on an object variable.
My new method is:
Direct2Entity* nextset[MAX_ENTS]; // ents[MAX_ENTS] is also a Direct2Entity* array
for(int i=0;i<MAX_ENTS;i++) {
nextset[i]=NULL; // note that ents[] is also flushed before this
}
int nextsetid=0;
int maxn;
bool stillnull;
while(true) { // infinite sorting loop
maxn=-1;
stillnull=true;
for(int i=0;i<next_put;i++) {
if (ents[i]!=NULL) {
stillnull=false;
if (ents[i]->depth<0) { // make sure no infinite loops occur with negative depth
ents[i]->depth=0;
}
if (ents[i]->depth>maxn) {
nextset[nextsetid++]=ents[i];
ents[i]=NULL; // make NULL to further loop
}
}
}
if (stillnull) break;
}
for(int i=0;i<next_put;i++) {
if (nextset[i]!=NULL) {
ents[i]=nextset[i]; // copy nextset[] to ents[]
}
}
for(int i=0;i<next_put;i++) {
if (ents[i]!=NULL) {
if (ents[i]->getroom()==current_room) {
ents[i]->draw(this); // ents[i] is still NULL... ?
}
}
}
In the last for loop, ents[i] was explicitly checked to make sure it would not be dereferencing NULL pointers. Yet C++ goes past it and calls the function. There are all sorts of run time error in all sort of random places, but I am almost sure it is undefined behavior coming from here.
I do not see the logic determining the value of next_put. Is it possible that it simply exceeds the length of ents[]? If so, even if you have properly initialized ents[], when your loop walks off the end of the array, that memory is not initialized (at least as you expect it to be) and your if (ents[i]!=NULL) will be passed (and then your program should crash).

I'm getting a stack overflow exception in C++ program

I am getting a system.stackoverflowexception.
I think it is happening somewhere inside the insert() function.
void insert(char* word){
int r1 = rand()%x; // Here is where I suspect the problem starts
int c1 = rand()%x;
if(gameBoard[r1][c1]=="") {
gameBoard[r1][c1] = word;
insertWordCopy(word);
} else
insert(word);
}
The following is incorrect, since it compares the pointers:
if(gameBoard[r2][c2]=="") {
As a result, the code almost certainly always goes down the else branch, resulting in infinite recursion.