Davigor
Davigor

Reputation: 403

Seeding rand() for random global variables

I'm trying to use C's rand() to initialize random inputs for a pseudo-random number generator. Due to constraints of a PRNG testing library I'm using, my generator function cannot accept any parameters, so it seems like I'll need to store the initial values as global variables.

Ideally, I would seed the generator with srand(time(NULL)), but this throws the "initializer element is not a compile-time constant" error when I try to do it globally.

What's the most straightforward way to do this? So far I've come up with passing the global variables into a function and doing the work there, like this:

unsigned int* w;
unsigned int* x;
unsigned int* y;
unsigned int* z;

void seed (unsigned int* first, unsigned int* second, unsigned int* third, unsigned int* fourth)
{
    srand((unsigned int) time(NULL));
    unsigned int a = rand();
    unsigned int b = rand();
    unsigned int c = rand();
    unsigned int d = rand();

    first =  &a;
    second = &b;
    third = &c;
    fourth = &d;
}

However, when I try to access my values in main, I get a EXC_BAD_ACCESS error in Xcode:

int main (void)
{
    seed(w, x, y, z);
    printf("%i", *w);     // throws error
...
}

... which I'm guessing has something to do with scope and the memory being freed before I want it to be. Don't have a ton of experience with C, but is this the right approach? If so how can I fix this error?

Thanks!

Upvotes: 0

Views: 1884

Answers (3)

tadman
tadman

Reputation: 211580

You're assigning pointers to values that exist only on the stack, not pushing things back like you think you are. Once that stack goes out of scope you're into dangerous territory.

Here's how it should be written:

void seed (unsigned int* a, unsigned int* b, unsigned int* c, unsigned int* d)
{
    srand((unsigned int) time(NULL));
    *a = rand();
    *b = rand();
    *c = rand();
    *d = rand();
}

int main() {
   // Note: These can be global, they're just put here for convenience
   // Remember, global variables are bad and you want to avoid them.
   unsigned int a, b, c, d;
   seed(&a, &b, &c, &d);

   // ...
}

Upvotes: 2

Ajay
Ajay

Reputation: 2643

The scope of variable a, b, c, d are within the seed function, so accessing those references outside the function will result unexpected results.
Either you need to pass address of variable to fill or allocate memory for each number in seed function.

Try below snippet

unsigned int w;
unsigned int x;
unsigned int y;
unsigned int z;

void seed (unsigned int* first, unsigned int* second, unsigned int* third, unsigned int* fourth)
{
    srand((unsigned int) time(NULL));

    *first =  rand();
    *second = rand();
    *third = rand();
    *fourth = rand();
}


int main (void)
{
    seed(&w, &x, &y, &z);
    printf("%i", w);
}

Upvotes: 1

Pras
Pras

Reputation: 4044

EXC_BAD_ACCESS is because you are assigning address of local variables from seed() to your pointers

These variable and their addresses will be invalid when seed() returns

Upvotes: 0

Related Questions