A problem with rand() and srand()

Here is a very simple program. It basically consists of three different files.

main.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include "./RandomHashes.h"

using namespace std;

int main(int argc, char* argv[])
{
    int a=6848;
    int *p;
    cout << *p << endl;
    assignRandomValue(p);
    cout << *p << endl;
    p++;
    assignRandomValue(p);
    cout << *p << endl;
    return 0;
}


RandomHashes.h
1
2
3
4
5
6
7
8
9
10
11
12
13
#ifndef RANDOM_HASHES
#define RANDOM_HASHES
// Header protection
#endif

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <ctime>
#include <cmath>


void assignRandomValue(int*);


RandomHashes.cpp
1
2
3
4
5
6
7
#include "./RandomHashes.h"

void assignRandomValue(int* addr)
{
    srand(time(NULL));
    *addr = rand();
}


And here is the output...
0
23804
23804



Now, I know that the first in the output is basically the initial value of the cell that pointer points to. And I know, the second 23804 is the random number assigned by function assignRandomValue(p) to the cell that p points to.
But the third 23804, shouldn't that be some other number?

I have possible explanations:

1- This might be by chance. Since the rand function assigns a random value to the variable and doesn't care if that value has or hasn't been assigned to any previous variable in the same program. If this was the case, the problem could be rectified simply by running the program once again. But I have executed the program again and again and although the value of the first cell changes every time, the value of the second cell is alway equal to the first one.

2- Another explanation is, maybe I am printing the same cell again and again. So, I went back to the main() and in lines 9, 11 and 13, removed the '*' from before the variable a.k.a 'p' so that the program will now print the addresses of the cells instead of the values. And the output indicated that the pointer is indeed getting incremented, pointing to the next integer cell in the memory (an increment of 4-bytes in the address)...

3- There is another possible explanation, which I am not sure if really is an explanation. But is this possible, that the since the random function is seeded by the current time, the value returned by time(NULL) hasn't changed yet while the main function calls for assignment to the next cell? In other words, the random function "calculates" the same value for both the cells because seed is same for both values? If this is possible, what is the workaround.

And I am not that proficient with C++, so I might be terribly wrong with the explanations or doing some stupid mistake somewhere that I am looking over.
Could anyone please point out the problem here?
And I don't know why, but the program has suddenly stopped working.
I haven't changed a thing there. But when I execute the file, it says "The program RandomHashes.exe has stopped working"...

If it helps, I am using Microsoft Windows 7 Pro with Code::Blocks 10.06
try to write srand(time(0))
When you create a pointer variable, it is uninitialized, like all other builtin types in C++.
So p doesn't point to anything valid and trying to dereference the pointer will cause the program to crash (if it doesn't crash, that's pure chance).
Also, srand initializes the random number generator - you should call it only once at the beginning of the program. Otherwise it's likely that you'll always get the same number.
Ok. That means two things.

1- I have to force the pointer to point at something. Can't leave it hanging there. Understood. There are several ways I can do that. Maybe initialize a variable and make the pointer point to it. I was actually thinking about creating an array of indefinite length (user can choose the length)... But that is okay, since for now I just want to print the array of random hashes. It would cause me problems later when I want to do something with that array. So that is solved, for now.

2- I should call srand(time(NULL)) outside the assignRandomValue(int*) function. And even outside the while loop inside the main function. Right? If that works, it is solved, too.

Thanks a lot.
I have the modified code here.

main.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include "./RandomHashes.h"

using namespace std;

int main(int argc, char* argv[])
{
    int *p;
    int cells = 10;
    int i = 0;
    srand(time(NULL));
    while (i<cells)
    {
        assignRandomValue(p);
        cout << *p << endl;
        p++;
        i++;
    }
    return 0;
}


RandomHashes.h
1
2
3
4
5
6
7
8
9
10
11
12
13
#ifndef RANDOM_HASHES
#define RANDOM_HASHES
// Header protection
#endif

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <ctime>
#include <cmath>


void assignRandomValue(int*);


RandomHashes.cpp
1
2
3
4
5
6
7
#include "./RandomHashes.h"

void assignRandomValue(int* addr)
{
    int a = rand();
    *addr = a;
}


The output is
21640
21575
9271
21130
2586
1282
13302
31427
21328
2813


Now I have made a few minor additions to the original code. I am looking for 10 random hashes instead of only two. So there is a while loop.

I have called srand(time(NULL)) only once, so that works alright.

However, something that I didn't understand is I haven't done anything with the pointer *p. The program doesn't crash. Do you still maintain that this is only a lucky coincidence? If it is so, please give me a better way to eliminate that anomaly.

I said in previous post that I could do it by initializing a variable and giving the address to *p. But if I define int temp; and then *p = temp;, does this assign the address or the value of temp to p?

It's just that I am always confused with pointers. I always have to keep a book or a tutorial as a reference with me, to be able to revise the pointer concepts every time I start writing a program which involves pointers (and almost all of them do)...
The int *p; creates a pointer pointing to a (within bounds) random place in memory; if that place is essential or used your program crashes because it attempts to change something it shouldn't, but that wouldn't happen in every run; that's why pointer arithmetic needs to be perfect or absent.
Also int temp; int *p=temp; is the same as int temp; int *p; p=temp;, so that doesn't make much sense. Essentially the asterisk (*) in int *p; and *p=7; mean two very different things; the first simply means that "the variable p is a pointer of int", while the second means "the contents of the address stored in p is 7"; to avoid that confusion pointers are most often declared as int* p; rather than int *p;.

BTW, I think you've done a mistake in your "Header protection"; It needs to be
1
2
3
4
5
6
#ifndef RANDOM_HASHES
#define RANDOM_HASHES

//  INCLUDEs PROTOTYPES ETC

#endif 

other wise it has no purpose, but instead only defines RANDOM_HASHES if it's undefined, but always includes and prototypes.
I didn't fully understand it. :\
I understand this part.
The int *p; creates a pointer pointing to a (within bounds) random place in memory; if that place is essential or used your program crashes because it attempts to change something it shouldn't, but that wouldn't happen in every run; that's why pointer arithmetic needs to be perfect or absent.

So, what can I do to make it perfect?

And about the header protection, I don't know a thing about header protection or any # things for that matter (excluding the #include directive). Code::Blocks automatically creates this header protection. So you mean that all the #include directives should come before that #endif ?
So I was just looking over the forums and I found this post.

http://www.cplusplus.com/forum/beginner/7961/#msg36878

And I think that is the solution to my problem. I should define an array with user input rather than leave the pointer hanging. Or I could use vectors but I haven't studied them yet.

Using dynamic allocation, I can use the array to further do operations on this array. For example, I want each random number to be unique throughout the array.

P.S. I dunno how to link the URL... So the address is underlined. I thought the forums would parse the links automatically.
Last edited on
One other question.
When srand() initializes the random number generator, does it make sure that no two random numbers generated must be equal or do I have to write code for that?
Topic archived. No new replies allowed.