Why Does My C++ Code Result in an Infinite Loop?

  • Context: C/C++ 
  • Thread starter Thread starter fluidistic
  • Start date Start date
  • Tags Tags
    C++ Logic
Click For Summary

Discussion Overview

The discussion revolves around a C++ code snippet that results in an infinite loop when attempting to generate random numbers between 1 and 3. Participants explore the logic behind the loop and suggest potential corrections and improvements.

Discussion Character

  • Technical explanation
  • Debate/contested

Main Points Raised

  • One participant describes the infinite loop issue and expresses confusion about the logic of the do-while condition.
  • Another participant points out that the variable declarations for x and xold inside the loop are masking the outer variables, suggesting their removal to resolve the issue.
  • A different participant proposes initializing xold to a value outside the range of random numbers to ensure a better chance of breaking the loop condition.
  • Some participants share a C# equivalent of the logic, illustrating how the same concept can be implemented in a different programming language.
  • A later reply acknowledges the variable masking issue and confirms that the program works correctly after the suggested change.

Areas of Agreement / Disagreement

Participants generally agree on the variable masking issue and its resolution. However, there are differing opinions on the initialization of xold and its impact on randomness, indicating that multiple views remain on how to best approach the problem.

Contextual Notes

The discussion highlights potential limitations in understanding variable scope and initialization in C++, which may affect the behavior of the code.

fluidistic
Gold Member
Messages
3,932
Reaction score
283
I don't understand why I enter in an infinite loop with the following code:
Code:
#include <iostream> //for cout
#include <cstdlib> //for rand()
#include <ctime> // for time()
#include <fstream> //to write into a text file
using namespace std;

static const int M = 3;

ofstream myfile;
int main()
{
	srand(time(0)); // set initial seed value to system clock
		myfile.open("data.txt", ios::app);
int x=0;
int xold=0;
int i;
do
{
	int xold=x;
	int x = rand() % M+1;
	myfile << x << endl;
	i++;
}
while(x-xold!=1 && x-xold!=-1);
cout << "It took" << i << "iterations"  << endl;


return 0;

myfile.close();
}

The idea is to generate a random number between 1 and 3, write it into a file. Repeat until the new random number differs by either +1 or -1 from the previous random number. With the current code, the loop never ends and in a matter of a few seconds my file.txt is filled by 1's, 2's and 3's up to several Mb's.
As I understand it, my do {...} wile(x-xold!=1 && x-xold!=-1) should continue when x-xold is not equal to 1 and when x-xold is not equal to -1. So if I get xold=0 and x=1, then x-xold=1 and the loop should stop because the first condition is not satisfied... but it doesn't stop at all.
I guess my logic is flawed but I'm blind and don't see it. Any help will be appreciated.
P.S.:I started c++ 5 days ago for fun.
 
Technology news on Phys.org
fluidistic said:
Code:
int x=0;
int xold=0;
int i;
do
{
	int xold=x;
	int x = rand() % M+1;
	myfile << x << endl;
	i++;
}
while(x-xold!=1 && x-xold!=-1);

You have defined two variables called xold, and two called x. Delete the "ints" inside the do-while loop.

FWIW a sensible compiler should give you a warning message if you "mask" one variable with another.
 
  • Like
Likes   Reactions: 1 person
Also, if you want to make the numbers be truly random, I would make the number int xold be something like 10, something far enough away from the range of the random numbers.

Otherwise, you will always be starting with xold = 0, and you will be more likely to break with the results 0, 1; (unless that was your intention).

Writing to console worked in C#...
Code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace PFPlayground
{
    class Program
    {
        static void Main(string[] args)
        {
            Random random = new Random();
            int x = 0;
            int xold = 10;
            int i = 0;

            do
            {
                xold = x;
                x = random.Next(1, 4);
                Console.WriteLine(x);
                i++;      
            }
            while (x - xold != 1 && x - xold != -1);
            Console.WriteLine("It took {0} iterations", i);

            Console.ReadLine();
        }
    }
}
 
  • Like
Likes   Reactions: 1 person
AlephZero said:
You have defined two variables called xold, and two called x. Delete the "ints" inside the do-while loop.

FWIW a sensible compiler should give you a warning message if you "mask" one variable with another.
Ah I see! I didn't even notice this. The program works fine now! Thanks!
TheDemx27 said:
Also, if you want to make the numbers be truly random, I would make the number int xold be something like 10, something far enough away from the range of the random numbers.

Otherwise, you will always be starting with xold = 0, and you will be more likely to break with the results 0, 1; (unless that was your intention).

Writing to console worked in C#...
Code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace PFPlayground
{
    class Program
    {
        static void Main(string[] args)
        {
            Random random = new Random();
            int x = 0;
            int xold = 10;
            int i = 0;

            do
            {
                xold = x;
                x = random.Next(1, 4);
                Console.WriteLine(x);
                i++;      
            }
            while (x - xold != 1 && x - xold != -1);
            Console.WriteLine("It took {0} iterations", i);

            Console.ReadLine();
        }
    }
}
Well spotted, thank you!
 

Similar threads

  • · Replies 22 ·
Replies
22
Views
4K
  • · Replies 5 ·
Replies
5
Views
3K
  • · Replies 10 ·
Replies
10
Views
3K
  • · Replies 23 ·
Replies
23
Views
3K
  • · Replies 1 ·
Replies
1
Views
2K
Replies
12
Views
3K
  • · Replies 8 ·
Replies
8
Views
2K
Replies
1
Views
2K
  • · Replies 4 ·
Replies
4
Views
6K
  • · Replies 7 ·
Replies
7
Views
1K