1

I'm developing in C using OpenVMS, I've done a code that put in a 1001 (0-1000) elements array, 1000 (0-999) random numbers between 0 and 50. Here is the code:

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

main(){
    int vet[1000], fre[50];
    int i;

    srand(time(NULL));

    for(i=0;i<1000;i++){
        vet[i]=(rand()%51);
    }

    for(i=0;i<1000;i++){
        printf("%d\n", vet[i]);
    }

    for(i=0;i<1000;i++){
        fre[vet[i]]=fre[vet[i]]+1;
    }

    for(i=0;i<51;i++){
        printf("The number %d  was generated %d times\n", i, fre[i]);
    }
}

When I show how much times each number was generated, I saw that the number 50 has a big number, sometimes more than double than others numbers, someone can help me?

SOLVED Code that works I must use srand() for now

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

main(){
        int vet[1000], fre[51] = {0};
        int i;

        srand(time(NULL));

        for(i=0;i<1000;i++){
                vet[i]=(rand()%51);
        }

for(i=0;i<1000;i++){
printf("%d\n", vet[i]);
}

        for(i=0;i<1000;i++){
                        fre[vet[i]]=fre[vet[i]]+1;
        }

        for(i=0;i<51;i++){
                printf("The number %d  was generated %d times\n", i, fre[i]);
        }
}
[EOB]

Thank you all

Mitro
  • 1,230
  • 8
  • 32
  • 61
  • 2
    The `rand()` PRNG is of very low quality. You'd better search for a better one, for example the [Mercenne twister](http://en.wikipedia.org/wiki/Mersenne_twister) generator, if you'd require a high quality PRN stream. If [GSL](http://www.gnu.org/s/gsl/) compiles on OpenVMS, it comes with many PRNGs. As a last resort, OpenVMS supports the `drand48` PRNG. On a side node, `fre` is never initialised (to all 0's). – Hristo Iliev Dec 10 '12 at 14:04
  • I' ve never used these other, I'll watch them this night, thank you! ;) – Mitro Dec 10 '12 at 14:17
  • [Solution](https://stackoverflow.com/a/75523944/6013016) – Scott Feb 27 '23 at 07:56

3 Answers3

5
    int vet[1000], fre[50];


    for(i=0;i<51;i++){
            printf("The number %d  was generated %d times\n", i, fre[i]);
    }

Problem 1: You declare fre to have 50 elements, but you use 51.

Problem 2: fre isn't initialised.

int vet[1000], fre[51] = {0};

should give you reasonable output.

Daniel Fischer
  • 181,706
  • 17
  • 308
  • 431
  • Why 51? The array doesn't start from 0? so when I write array[50] are 0,1,2,...,49,50?? the total is 51, I don't understand if I write 51 I can put in the array 52 elements, I' m wrong? – Mitro Dec 10 '12 at 14:10
  • 1
    No, `type array[N];` declares an array of `N` elements of type `type`. The valid indices are `0` to `N-1`. So `int fre[50];` gives you indices 0 to 49. To use index 50, you need 51 elements. – Daniel Fischer Dec 10 '12 at 14:14
  • Ok thank you now works!! Why showed me so a big number at 50? What happened? – Mitro Dec 10 '12 at 14:25
  • 1
    @AlessioMTX A lot of things could have happened. Reading/writing past the array bounds is undefined behaviour, so what actually happened depends on the implementation, compiler options, ... . Possibly you just wrote to and read an unused memory slot containing garbage, or a stack protector, or the reurn address, I don't know. – Daniel Fischer Dec 10 '12 at 14:30
  • @Joze Actually, it's better if the code segfaults upon undefined behaviour, IMO. If it does, it's a clear message, if it doesn't, you may not notice that there's anything wrong at all. – Daniel Fischer Dec 10 '12 at 14:32
  • I was obviously joking ! I totally agree ! – Joze Dec 10 '12 at 14:35
  • 1
    Segfault is a type of error you got for different reasons such as access violation. In your case, you had huge probability of getting this error. When you got this error, your program will totally crash ! More information about it here : http://en.wikipedia.org/wiki/Segmentation_fault Every C programmer have faced this error, at least once ! :) – Joze Dec 10 '12 at 14:37
  • Oh yes, it happened to me XD, but I didn't know that this was his name! – Mitro Dec 10 '12 at 14:40
3
int vet[1000], fre[50];

Your vet[] array has 1000 entries, not 1001. fre[] has 50, not 51. If you are generating numbers from 0 to 50, you need to declare fre[] as fre[51];

You also never clear your fre[] array before accumulating the results.

JasonD
  • 16,464
  • 2
  • 29
  • 44
  • The array doesn't start from 0? so when I write array[50] are 0,1,2,...,49,50?? the total is 51, I don't understand – Mitro Dec 10 '12 at 14:09
  • 1
    Arrays start from zero, but the number is the number of elements, not the maximum index. So fre[50] gives fre[0] .. fre[49] – JasonD Dec 10 '12 at 14:10
  • 1
    By indexing off the end of your array, you were accessing memory used by something else, with unpredictable results. – JasonD Dec 10 '12 at 14:27
1

1) Initialize your variables before you use them:

int vet[1000] = {0};
int fre[50] = {0};

2) You're checking for values outside the array size:

for(i=0;i<51;i++){  

should be:

for(i=0;i<50;i++){

Your array fre[50] has elements fre[0] through fre[49]. So you want your count to start at 0 and go to <50, ie 49.

3) You're generating numbers outside your array size:

vet[i]=(rand()%51);

should be:

vet[i]=(rand()%50); 

rand() % x will generate a number between 0-(x-1), if your array is size 50 then its elements are 0-49, which means you need to pick %50 or else you'll go over the array size when assigning with: fre[vet[i]]=fre[vet[i]]+1;

4) Keep in mind that rand() function generates pseudo-random output, so there's always the chance it won't be as "random" as you wanted.


EDIT
Ok, your comment: 2) No because I'm checking also 0 makes me think you don't understand how arrays work:

int fre[50] = {0};

gives you an array of 50 elements. The index of arrays start at 0 and go to [number of elements - 1], such that:

first element -->fre[0], fre[1], fre[2], ..., fre[48], fre[49] <-- last element

If you want to record values from 0 to 50 inclusive you need 51 elements in your array:

int fre[51] = {0};

So both of these:

for(int i=0; i<50; i++)    and    for(int i=0; i<51; i++)

start at 0, and run through each element, but the former works on fre[50] (fifty elements from 0 to 49) and the latter works on fre[51] (fifty one elements, from 0 to 50)

Mike
  • 47,263
  • 29
  • 113
  • 177
  • 3) If I do %50 I have number from 0 to 49 – Mitro Dec 10 '12 at 14:15
  • 2) No because I'm checking also 0 – Mitro Dec 10 '12 at 14:16
  • @AlessioMTX - yup, you have to do that so you don't overflow your array of `fre[50]`. If you want to do numbers from 0-50 you have to increse the size of `fre` by 1. – Mike Dec 10 '12 at 14:16
  • I have done int fre[51] as Daniel and Jason told me. And now works. I haven't any overflow. – Mitro Dec 10 '12 at 14:21
  • 37 20 25 24 40 36 0 50 49 27 23 These are some numbers and in the 1000 elements I have min 0 max 50 – Mitro Dec 10 '12 at 14:22
  • No I understand how array works, if I put 50 instead of 51 the run will show me until The number 49 was generated X times – Mitro Dec 10 '12 at 14:29