Why is my loop in my recursive function infinite? [closed] - c++

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 8 years ago.
Improve this question
I have the following function that recursively checks each square in a sudoku puzzle to make it legal, and I kept getting a segmentation fault when it ran, so I put cout checks everywhere to see where it broke. Somehow, it stays in the loop and continues to call the addSquare function over and over, without ever ending. How do I get it to stop?
bool DoTheWork::addSquare(int& depth)
{
depth++;
cout << depth << endl;
if(board.checkZeroes()==false){ //if the game is won, return true
cout << "ifstatement1" << endl;
return true;
}
else {
for(int i = 0; i < 10; i++) {
cout << "loop1" << endl;
for(int j = 0; j < 10; j++) {
cout << "loop2" << endl;
if(this->board.getSquare(i,j)==0) { //go through each
cout << "ifstatement2" << endl;
for(int k = 1; k < 10; k++) {
cout << "loop3" << endl;
//try each number in that square for legality
board.setSquare(i,j,k);
//set that square to the number you are currently on
if(board.isLegal()==false) {
cout << "ifstatement3" << endl;
board.unsetSquare(i,j);
}
//if the board is not legal for that number, unset that square
if(addSquare(depth)==true) {
cout << "ifstatement4" << endl;
return true;
}
//recursive function, if method is true then it will return true
board.unsetSquare(i,j);
}
}
}
}
}
return false;
} // bool DoTheWork::addSquare(int& depth)
When run in the terminal, it prints the following:
loop 1
loop 2
ifstatement2
loop3
ifstatement3
130964
loop1
...
and onwards until it says "Segmentation fault (core dumped)"
The number after "ifstatement3" increases by 1 each time the depth increases.
Including the checkZeroes function below:
bool Board::checkZeroes()
{
bool zeroPresent = false;
//assume there are no zeroes, easier for coding
for(int i=0; i<9; i++) {
for(int j=0; j<9; j++) {
if(theBoard[i][j] == 0){
//go through each value of theBoard, if any are 0 return true
zeroPresent = true;
}
}
}
return zeroPresent;
} // int Board::checkZeroes()

You never change the value of depth that will cause infinite recursion and a segmentation fault will happen when the stack access memory that should not be accessed.
I would run it in a debugger like GDB or DDD in linux.

Related

why am I getting runtime error for the following code and how to fix that? [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 2 years ago.
Improve this question
I was solving this problem on Codeforces B. Ania and Minimizing and I got runtime error on test 9. I am new to c++ and I did not understand why this happened. Could someone help me fix this error? Thanks :)
Here is my code:
#include <iostream>
using namespace std;
int main(){
ios_base::sync_with_stdio(false);
cin.tie(NULL);
int n, k;
string num;
cin >> n >> k;
cin >> num;
if(n==1){
cout << 0 << endl;
return 0;
}
if(k==0){
cout << num << endl;
return 0;
}
if(num[0]!='1'){
num[0]='1';
}
else{
k=k+1;
}
for(int i=1; i<k; i++){
if(num[i]!='0'){
num[i]='0';
}
else{
k=k+1;
}
}
cout << num << endl;
return 0;
}
Here you can check the runtime error details:
https://codeforces.com/submissions/iwrestledthebeartwice at submission number: 85825935
If k is larger then the size of num (which could happen because you are incrementing it at line 37) you will get an "access out of bonds" Error at num[i]='0'.
For example you have the following inputs:
5 5
12345
This will cause line 33 to access memory past the size of num. now it depends if this memory is 0, then your code will work. But if it is not zero you try to write a zero which is not permitted.
Your code makes out of bounds string accesses on some inputs, for instance given n=2 k=1 S=10 you access num[2] which does not exist. This will cause the runtime error that you see.
Your problem:
for(int i=1; i<k; i++){
if(num[i]!='0'){
num[i]='0';
}
else{
k=k+1;
}
}
You are reading and writing past the end of the buffer (buffer overrun). Supoose n = 3, and k=3. and the number is 1000. You will find 0 in all positions and your k will be incremented on every iteration, making it 6 by the end. While the string was just 4 chars long. You read and wrote to a location which you are not allowed to. That is undefined behaviour.
To fix, you need to make sure you don't change k while you are looping as that is totally unnecessary. Also, make sure you read and understand the problem statement completely before attempting to solve the problem.
Let's remove the k = k + 1 from both places and make sure we are always less than n. i needs to do at least k iterations
if(num[0]!='1'){
num[0]='1';
}
for(int i=1; i <= k && i < n; i++){
if(num[i]!='0'){
num[i]='0';
}
}
Additionally, if our first digit is '1', we have one less 0 to replace, so we will decrement k by 1 in that case:
if(num[0]!='1'){
num[0]='1';
k--;
}
This will solve the issue and you will get correct output. You still need to place additional checks to make sure num.size() == n always and that k < n always.
Note that this might not be the most efficient or best solution, it only attempts to fix the issues you had with the logic you used.
As all of you guys pointed out I fixed my code. I was dumb and making the loop go out of bounds.
Here is the code:
#include <iostream>
using namespace std;
int main(){
int n, k;
string num;
cin >> n >> k;
cin >> num;
if(k==0){
cout << num << endl;
return 0;
}
if(num.size()!=n){
return 0;
}
if(n==1){
cout << 0 << endl;
return 0;
}
if(k==0){
cout << num << endl;
return 0;
}
if(k>num.size()){
cout << num << endl;
return 0;
}
if(k>n){
cout << num << endl;
}
if(num[0]!='1'){
num[0]='1';
k--;
}
for(int i=1; i<=k and i<n; ++i){
if(num[i]!='0'){
num[i]='0';
}
else{
k=k+1;
}
}
cout << num << endl;
return 0;
}

Quit while (true) loop in C++ [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 2 years ago.
Improve this question
This is my simple while (true) loop:
while (true)
{
int i = 0;
++i;
cout << i << endl;
if (i == 5) {
break;
}
}
}
So break; isn't quitting the loop and the output is an infinite 1.
See this for Why use a for loop instead of a while loop?.
Now, coming to your question:
You are initializing i variable in each iteration of your while loop. Move the definition of i outside the while loop so that it's value can be updated.
Try this:
#include <iostream>
int main(void)
{
int i = 0;
while (true)
{
++i;
std::cout << i << std::endl;
if (i == 5)
break;
}
return 0;
}
Output:
1
2
3
4
5
Suggestion:
You can also use for loop as it is more appropriate to print a range of numbers.
#include <iostream>
int main(void)
{
for (int i = 1; i <= 5; i++)
std::cout << i << std::endl;
return 0;
}
The i is always initialized to 0 on each iteration. You should use this outside of the loop.
You are creating a new variable i in every run of the loop.
It is initalized to zero, then you increase it by one.
So after
int i = 0;
++i;
the variable i is always 1.
Solution:
int i = 0;
while (true) {
{
++i;
cout << i << endl;
if (i == 5) {
break;
}
}
}
or you can just use a simple for-loop:
for (int i = 0; i <= 5; i++)
{
cout << i << endl;
}

Can't figure out why while loop is infinite

My code uses what I thought would be a simple while loop. It checks if the randCard already exists in the vector I have and, if it does, makes a new randCard.
I've added cout statements within the loop to try to find which processes it's running through and discovered it's only running through the while loop, none of the nested for loops. The problem is as follows:
bool isSame = true;
//Make sure they don't be the same cards
while (isSame){
cout << "While entered" << endl;
for(int i = 0; i < notToUse.size(); i++){
if(randCard == notToUse.at(i)){
randCard = rand() % 24;
}
cout << "First for ran" << endl;
}
for (int i = 0; i < notToUse.size(); i++){
if (randCard == notToUse.at(i)){
cout << "Recheck loop" << endl;
break;
}
else{
cout << "Else ran" << endl;
isSame = false;
}
}
}
randCard is from a class of type Cards. The vector notToUse consists of cards indices that have already been used. The end cout statements end up looking like:
While entered
While entered
While entered
While entered
While entered
It seems like the for loops aren't even accessed. How can I fix this?
For anyone who might stumble upon this, the answer was resolved in the comments. The vector was of size 0, so the for loops didn't even run.

C++ For-Loop Gets stuck when entering new variables [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about programming within the scope defined in the help center.
Closed 8 years ago.
Improve this question
I'm new to C++ and trying to create a lottery game for a college project.
I have a for loop to check that there are no duplicate numbers in the array entered. This works absolutely fine when you take out the section of code to produce the random numbers.
As soon as I add the random number section back in, the for loop just gets stuck. It will continuously tell me that i have already entered the number when its trying to store the first number.
I have attached all of my code, apologies if you don't need it all.
#include <iostream>
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
using namespace std;
//int loto[6];
int main()
{
int numbers[6];
//void rand_num(int loto[6], int count);
int loto[6]; //used to store the loto numbers
//int james = 0;
//int l,j; //used in checking any duplicated
srand(time(0));
for(int count=0; count<6; count++)
{
loto[count] = (rand()%49)+1;
cout << loto[count] << endl;
}
//declares the variable i to increase each time a number is entered.
//this will only go as high as 6
for(int i=0;i<6;i++)
{
cout<<" " << i<<" : Please enter your lottery numbers: "<<endl;
cin>>numbers[i];
if ((numbers[i] >= 50) | (numbers[i] == 0))
do
{
{
//checks to see if the first number entered is above 50 or = to 0 and rejects it
cout << "The Number must be between 1-49, please select again. " << endl;
cin >> numbers[i];
}
}
while ((numbers[i] >= 50) | (numbers[i] == 0));
//----------------------------------------------------------------------------
//this section of code is a loop within a loop to check the number entered against all numbers already stored.
//makes l the same as i effectively
for(int l=0;l<6;l++)
{
//makes j one more than l
for(int j=l+1;j<7;j++)
{
if( numbers[l] == numbers[j] )
do
{
{
cout << "Number has already been chosen, please re-enter number " << endl;
cout << endl;
cin >>numbers[i];
//checks the number that is re-entered is not <50 or = 0
//if so it rejects it and asks for another as above.
if ((numbers[i] >= 50) | (numbers[i] == 0))
do
{
{
cout << "The Number must be between 1-49, please select again. " << endl;
cin >> numbers[i];
}
}
while ((numbers[i] >= 50) | (numbers[i] == 0));
}
}
while (numbers[l] == numbers[j]);
}
}
}
//----------------------------------------------------------------------------
//this displays the numbers that have been chosen.
cout << "Your Numbers are: " << endl;
for (int i = 0; i<6; i++)
{
cout << " " << numbers[i];
}
return 0;
}
I'm not sure this is the real problem but it is a bug. Try to correct it and see if it helps.
for(int l=0;l<6;l++)
{
//makes j one more than l
for(int j=l+1;j<7;j++)
{
if( numbers[l] == numbers[j] )
The inner-loop will reach j==6 so you will access outside the array. The outer-loop shall have 5 as the limit and the inner-loop shall have 6 as the limit.
EDIT:
After looking a bit more at your code I can see that you are using numbers[] without initializing it. The two nested for-loops will compare all elements in numbers. But if the user have only entered 2 numbers, the rest is unitialized and can give unintended results.
Further - you don't need to check all elements againt all elements every time. Just check the newly entered number (index by i) with all previous numbers.
Finally you will probably need something like:
if (!(cin >> numbers[i])) {
cout << "Please enter numbers only." << endl;
cin.clear();
cin.ignore(10000,'\n');
}
to handle input not being integer, e.g. "text"
And to minor things:
You should also check for negative numbers.
You are using | instead of ||. It will work fine but || seems more correct as it is the logical OR (while | is a binary OR).

c++: Trouble detecting ascension of numbers in an array

I'm a novice to c++ programming and currently taking a class as an introduction to programming. I am currently working on a homework project where I input 10 integers and determine whether the numbers are in ascending order or not.
The issue I'm having is that the program always thinks there is a ascension, no matter the input provided. I figured the problem lies in the IsInOrder() function's for loop, however I can't figure out why exactly it isn't working or how to fix it.
Another potential problem is how to determine ascension for all values, for instance if my code worked I think it would count [1, 2, 3, 4, 5, 1, 2, 3, 4, 5] as an ascension, even though it's not.
I've tried searching online and have found a few similar assignment questions, but with no answer to these problems.
Here's the code I have so far:
#include <iostream>
using namespace std;
bool IsInOrder (int numHold[]);
//This portion takes the numeral inputs and outputs the answer
int main()
{
int numHold[10];
bool status;
cout << "Welcome to the Ascension detector 5000" << endl;
cout << "This program will detect whether the numbers you input are in ascending
order" << endl;
cout << "Isn't that neat?" << endl <<endl;
for (int i=0; i < 10;i++)
{
cout << "Please enter a number: ";
cin >> numHold[i];
}
cout << endl;
for(int i=0;i < 10;i++)
{
cout << numHold[i] << endl;
}
status = IsInOrder(numHold);
if (status == true)
{
cout << "The numbers are in ascending order" << endl;
}
else
{
cout << "The numbers are not in ascending order" << endl;
}
system("PAUSE");
return 0;
}
//This function determines whether the inputs are in ascending order
bool IsInOrder (int numHold[])
{
for (int i = 0; i < 10; i++)
{
if (numHold[i] < numHold [i++])
{
return false;
}
else
{
return true;
}
}
}
Appreciate any help in advance and sorry if the code isn't well formatted, the code wasn't copy/pasting well in to the code sample.
in IsInOrder Function, run for loop till i<9 and remove else part and put return true outside the for loop.
Why return true outside the for loop?
Because return true only when you checked all the element, not every time. Take a look at your code you'll get it.
Your IsInOrder routine doesn't check all the values in the array, it returns immediately after encountering two different numbers.
Also, if it would run through the entire array (i.e. when all the numbers would be the same), it would have checked 11 elements by the time it ended instead of 10, and it wouldn't return anything.
bool IsInOrder(int numHold[])
{
bool inOrder = true;
for (int i = 0; i < 9; i++)
{
if (numHold[i] > numHold[i+1])
{
inOrder = false;
break;
}
}
return inOrder;
}
Firstly, the true and false branches are the wrong way round.
Secondly (assuming true/false has been fixed), you conclude that the entire sequence is in the ascending order as soon as you've seen two numbers that are in order. That's not correct: you can't return true until you've examined every pair.
Lastly, the loop's terminal condition is off by one.
bool IsInOrder(int numHold[]) {
for (int i = 0; i < 9; i++) {
if (numHold[i] >= numHold[i+1]) {
return false;
}
}
return true;
}