-2

I wrote a program that create a string array which contains random strings, and the rand_str() is to make a string of 20 length long. When I use sleep(), the result is exactly what I want. However, I think sleep() shouldn't appear in my code. Removing sleep(), the random strings created are totally different. I am really confused about this. Could someone help to explain why this happens?

#include <iostream>
#include <string.h>
#include <random>
#include <ctime>
#include <cstdlib>
#include <windows.h>
#include <stdlib.h>
#include <array>
#define show(w) for(auto val:w){cout<<val<< " ";}cout<<endl;
using namespace std;

char *rand_str(char *str,const int len);

int main(){
    const int len = 10;
    char *a[len];
    string c[len];
    array<string,len> ar;char b[len][21];
    for (int i = 0; i < len; ++i) {
        ar[i] = rand_str(b[i], 21);
        fflush(stdin);
//      Sleep(1000);
    }
    show(ar);
    return 0;
}
char *rand_str(char *str,const int len){
    srand(time(NULL));
    int i;
    for(i=0;i<len;++i)
    {
        switch((rand()%3))
        {
            case 1:
                str[i]='A'+rand()%26;
                break;
            case 2:
                str[i]='a'+rand()%26;
                break;
            default:
                str[i]='0'+rand()%10;
                break;
        }
    }
    str[len - 1]='\0';
    return str;
}

Not using sleep() :

enter image description here

Using sleep() :

enter image description here

Nghia Bui
  • 3,694
  • 14
  • 21
Merediii
  • 1
  • 3
  • 3
    Please include the code in the question. Links can break and images cannot be compiled, hence code is always prefered – 463035818_is_not_an_ai May 21 '19 at 15:53
  • Sorry I'm new here~ – Merediii May 21 '19 at 15:56
  • You need to provide enough code for us to reproduce the issue, or at least compile your code: we don't know what `rand_str` does, so we cannot work out what kind of interactions might be causing this behavior. – Xirema May 21 '19 at 15:57
  • Use /dev/random in Linux or look here https://stackoverflow.com/questions/322938/recommended-way-to-initialize-srand – Fausto Carvalho Marques Silva May 21 '19 at 16:00
  • `/dev/random` is not portable. And sometimes you don't want truly random numbers. Controlling the seed lets you re-run the program with the same "random"-number, which makes debugging much easier. – HAL9000 May 21 '19 at 16:12

4 Answers4

3

The program you've written executes quickly enough that it is extremely likely that every single loop of rand_str will occur in the span of a single second. This is important because your method for generating strings involves calls to time, because time returns a time_t object, which is specified in the C-standard as:

The encoding of calendar time in time_t is unspecified, but most systems conform to POSIX specification and return a value of integral type holding the number of seconds since the Epoch. Implementations in which time_t is a 32-bit signed integer (many historical implementations) fail in the year 2038.

time, C++ Reference

So if the entire program executes in under a second, every single call to time in that span will return the same value, seeding your random numbers with the same value each time, and producing identical output on each loop. Conversely, when you Sleep for 1000 milliseconds (1 second), you nearly guarantee that each execution will have a different seed, and thus different output.

In general, you should only seed the random numbers once, at the start of your program. Alternatively, you should consider leaning how to use the <random> library, since it contains far better mechanisms for generating Random Numbers.

Community
  • 1
  • 1
Xirema
  • 19,889
  • 4
  • 32
  • 68
2

rand_str most likely has some kind of time-dependence associated with it. The one you present has a seed set to srand(time(NULL)); so it certainly does.

And Sleep(1000) (which will be a minimum sleep of 1000 units) is enough to change the result.

Removing the sleep call and your program execution is fast enough for the time-dependence of rand_str to be unobservable.

Bathsheba
  • 231,907
  • 34
  • 361
  • 483
1

Your rand_str function re-seeds the PRNG on every single call, and it does so using the current time in seconds. It then pulls out the "first" number in that sequence and returns it.

That means you only get a different pseudo-random sequence for function calls for different seconds in time. If you make multiple function calls within the same second, you keep re-seeding with the same seed, which results in the same sequence, and the first number in that same sequence is the same number always returned. That's why the sleep makes a difference: it changes the seed.

You should only seed once, at the start of your program, then just use the resulting sequence as needed.

Incidentally, this entire methodology is outdated. Since C++11, we do random numbers like this.

Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055
-1

This is most likely due to the fact that computers cannot produce truly random numbers. Hence, there exists a concept called a seed. And the most common seed for pseudo-random number generation is the time. Making your program wait a bit will make it run the random generator with a different seed.

Rokas Višinskas
  • 533
  • 4
  • 12
  • Are u suggesting that the random number generated in 1 ms is all the same due to the seed? – Merediii May 21 '19 at 16:01
  • @Merediii That's exactly correct, but it's the fault of your code, not of the random number generator. You didn't have to use time as seed, you didn't have to use _seconds-resolution_ time as seed, and you didn't have to seed over and over again. :) – Lightness Races in Orbit May 21 '19 at 16:02
  • Looking at `rand_str()` this is exactly what it is going on. The function uses the time to initialize the seed in the start of the function. But since the function is restarted many times in a short time span. The clock will have no time to advance so you will always seed with the same value and get the same pseudo-random numbers. (The resolution of `time()` is typically 1 second). The correct solution is to call `srand()` *once* at the start of your program. – HAL9000 May 21 '19 at 16:08
  • "computers cannot produce truly random numbers" Yes they can with special hardware although at the time of writing they are extremely slow cf. a pseudo generator. – Bathsheba May 22 '19 at 06:48