Thread: stuck with rand() function

  1. #1
    Registered User
    Join Date
    Oct 2003
    Posts
    55

    stuck with rand() function

    Below is part of my program ... i did some modification so it will be easier to understand ... i tried to generate some random numbers for my card arrays but once i execute it ... the program seems to be STUCK ...

    i use Microsoft Visual C++ 6.0 as compiler
    the compiler detects no errors with my program ...

    --------------------Configuration: Untitled1 - Win32 Debug--------------
    Compiling...
    Untitled1.cpp
    Linking...

    Untitled1.exe - 0 error(s), 0 warning(s)

    Code:
    #include <iostream>
    #include <cstdlib>
    
    using namespace std;
    
    void gen();
    void initial_card();
    void initial_called();
    
    int card[5][5][4];
    int called[25];
    int number;
    int x, y, z;
    
    int main()
    {
    	initial_card();
    	initial_called();
    
    	cout << "Test" << endl;
    
    	for(z=0; z<4; z+=2)
    	{
    		for(x=0; x<5; x++)
    		{
    			for(y=0; y<5; y++)
    			{
    				gen();
    				card[x][y][z]=number;
    				card[x][y][z+1]=number;
    			}
    		}
    		initial_called();
    	}
    
    	cout << "Test Again !!" << endl;
    
        system("PAUSE");
        return 0;
    }
    
    void gen()                // something wrong here i think ...
    {
    	do
    	{
    		number=(rand()%25)+1;
    
    		if(called[number]==0)
    		{
    			called[number]=1;
    			break;
    		}
    	}while(true);
    }
    
    void initial_card()
    {
    	for(z=0; z<4; z++)
    	{
    		for(x=0; x<5; x++)
    		{
    			for(y=0; y<5; y++)
    				card[x][y][z]=0;
    		}
    	}
    }
    
    void initial_called()
    {
    	for(x=0; x<26; x++)
    		called[x]=0;
    }
    anyone mind to explain to me why this happen ?

  2. #2
    Registered User jlou's Avatar
    Join Date
    Jul 2003
    Posts
    1,090
    Your called array has a size of 25, meaning indexes 0 through 24 are valid.

    In initial_called(), your for loop goes from 0 to 25, so it is writing over the end of the array.

    That is not your problem, though. Inside gen(), you are trying to generate a random number that falls within the valid array indexes, but instead of generating something between 0 and 24, you are generating something between 1 and 25.

    When I fixed those two problems your program no longer fell into the infinite loop.

  3. #3
    Registered User
    Join Date
    Oct 2003
    Posts
    55
    how come the program will fall into a infinite loop one ?
    is it because of the initial_called() or because of gen() ?

    i am still new to the language ~

    mind showing me the correct source code ?

  4. #4
    Registered User jlou's Avatar
    Join Date
    Jul 2003
    Posts
    1,090
    I don't know exactly what you are trying to do, but it appears that inside gen() you are attempting to generate random numbers until you find one that hasn't been called yet. When you do, you set the array value at that index to 1 so that it won't be called again. Since your array has a size of 25, you can do this 25 times before the array is full. Luckily, you reset the array to all 0's after 25 times calling gen(), so your idea should work just fine.

    Let me try to explain the problem graphically. When you declared int called[25];, it created 25 consecutive ints in memory. The next thing you declared is int number;, which just happens to be right after the called array in memory. So before the program does anything, the uninitialized memory looks like this:
    Code:
    ...         called            number    <-- Variable name
            0   1   2   ...  24             <-- Array index
    ...   [ ? | ? | ? | ... | ? ]   ?       <-- Memory value
    You then call initial_card() and initial_called();. Inside initial_called(), you set array indexes 0 though 25 to 0. That overwrites the array. Luckily for you, the variable number is next in memory, and it just gets set to 0 accidentally without any real problems. (NOTE: Don't count on this to happen, never overwrite your array on purpose). So after calling initial_called(), your memory looks like this:
    Code:
    ...         called            number    <-- Variable name
            0   1   2   ...  24             <-- Array index
    ...   [ 0 | 0 | 0 | ... | 0 ]   0       <-- Memory value
    Next, you enter your three for loops in main(). Inside the loops, gen() is called once. Inside gen(), a random number is generated - 16, and your code adds one to it making it 17. Since called[17] == 0, you set called[17] = 1;, and memory looks like this:
    Code:
    ...         called                      number    <-- Variable name
            0   1   2   ...  17   ...  24             <-- Array index
    ...   [ 0 | 0 | 0 | ... | 1 | ... | 0 ]   0       <-- Memory value
    In your for loops, gen keeps getting called, and each time it finds a new random number and sets that array value to 1. At some point, like maybe the 6th call to gen(), the random number is 24, and since you add 1, that makes 25. However, your array only goes from 0 to 24, so again you access memory passed the end of your array. Your code checks that array[25] == 0, but since that is really the number variable, which at this point is 25, your check returns false. In fact, whenever the random number generates 24, to which you add 1 to make 25, the if statement will always return false, because number is never 0 at that point. Look at the memory when the if statement is called with number = 25:
    Code:
    ...         called                      number    <-- Variable name
            0   1   2   ...  17   ...  24             <-- Array index
    ...   [ 0 | 1 | 0 | ... | 1 | ... | 0 ]   25      <-- Memory value
    Since the compiler thinks that number is called[25], it will always return false for if(called[25]==0).

    So anyway, because of that, by the time gen() has been called 24 times, your memory looks like this:
    Code:
    ...         called                      number    <-- Variable name
            0   1   2   ...  17   ...  24             <-- Array index
    ...   [ 0 | 1 | 1 | ... | 1 | ... | 1 ]   ??      <-- Memory value
    Notice that the array value at index 0 is still 0. This is because you add 1 to your random number, and so you never actually get 0. On the 25th call to gen, it tries to find a number from 1 to 25 that hasn't been called yet. The previous 24 calls to gen() set the numbers 1-24, so only 25 is left, but because that is passed the end of the array like I explained above, the if statement always returns false. The code can't find a suitable number, so it goes on forever.

    The solution of course is to stop accessing data past the end of the array. In intial_called(), you should only set the values to 0 for indexes from 0 to less than 25. And in gen(), you should be generating random numbers from 0 to 24, NOT from 1-25.
    Originally posted by stalker
    mind showing me the correct source code ?
    Sorry, I won't show you the correct source code, because then you wouldn't learn. That last paragraph should help you understand how to fix it if the novel above didn't. If you still have troubles then maybe somebody else can explain it better.

  5. #5
    Registered User
    Join Date
    Oct 2003
    Posts
    55
    i found out how to deal with it after your explanation .....
    thanks for your help ~

    Code:
    void gen()           
    {
    	do
    	{
    		number=(rand()%25)+1;
    
    		if(called[number-1]==0)
    		{
    			called[number-1]=1;
    			break;
    		}
    	}while(true);
    }

  6. #6
    Registered User jlou's Avatar
    Join Date
    Jul 2003
    Posts
    1,090
    Congrats! That will work fine.

    I would have just removed the +1 part like this, but at least you were able to find a solution.

    Code:
    void gen()           
    {
        do
        {
            number=(rand()%25);
    
            if(called[number]==0)
            {
                called[number]=1;
                break;
            }
        }while(true);
    }

  7. #7
    Registered User
    Join Date
    Oct 2003
    Posts
    55
    i cant remove the +1 because i am writing a bingo simulation ( 1-25) and 0 is not a valid number ....

    anyway thanks for your help ... i understand more about arrays now

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 6
    Last Post: 10-23-2006, 07:22 PM
  2. string array stuck:(
    By mass in forum C Programming
    Replies: 18
    Last Post: 05-22-2006, 04:44 PM
  3. Program stuck in infinite loop-->PLEASE HELP
    By Jedijacob in forum C Programming
    Replies: 5
    Last Post: 03-26-2005, 12:40 PM
  4. Stuck on random generating
    By Vegtro in forum C++ Programming
    Replies: 3
    Last Post: 10-01-2003, 07:37 PM
  5. stuck ky
    By JaWiB in forum Tech Board
    Replies: 2
    Last Post: 06-15-2003, 08:28 PM