0

I'm having problems with this code because when I run it i get an infinite loop with the number random generator. What I'm trying to do is to assign to an array , 99 numbers from 1 to 9 and then make some mathematical simple operations.

#include <stdio.h>
#include <stdlib.h>
#define SIZE 99
void mean(const int a[]);
void median( int a[]);
void mode(int freq[] , const int a[]);

int main (void) {
   int response[SIZE];
   int frequency [10];
   int i;
   srand(time(NULL));
   for (i = 0; i<= SIZE ; i++) {
      response[i] = (rand() % 6) +1 ;
      printf("%d", response[i]);
   }
   mean(response);
   median( response);
   mode(frequency , response);

return 0;
}


void mean(const int a[]){
   int j , total = 0;
   float mean;
   printf("********\n%6s\n********\n\nThe mean is the average value of the data\nitems.", "Mean");
   printf("The mean is equal to the total of\n all the data items");
   printf("divided by the number\n of data items (%d):", SIZE);
   for( j = 0 ; j <= SIZE ; j++){
      total += a[j];
   }
   mean = (float) total / SIZE;
   printf("The mean value for\nthis run is %d / %d = %f", total, SIZE, mean);
}

void median( int a[]){
   int i, j, n, median, hold;
   n=1;
   hold = 0;
   printf("********\n%7s\n********\n\nThe unsorted array of responses is\n", "Median");
   for (i=0;i<=SIZE;i++){
      if ((i/10) <= n){
         printf("%d", a[i]);
      }
      else{
         printf("\n");
         n++;
      }
   }
   printf("The sorted array is\n");
   for(i=0;i<=SIZE;i++){
      for(j=0;j<=SIZE-1;j++){
         if (a[j]>a[(j+1)]){
            hold = a[j];
            a[j] = a[ (j + 1)];
            a[ (j + 1)] = hold;
         }
      }
   if ((i/10) <= n){
         printf("%d", a[i]);
      }
      else{
         printf("\n");
         n++;
      }
   }
   median = a[SIZE/2];
   printf("The median is element %d of\nthe stored %d element array.\n", SIZE/2 , SIZE);
   printf("For this run the median is %d", median);
}

void mode ( int freq [] , const int a[]){
   int j, o, mode , i, rating;
   printf("********\n%6s\n********\n\n%10s%12s%12s", "Mode" ,"Response" ,"Frequency", "Histogram");
   for(j=0; j<= SIZE ; j++){
      ++freq[a[j]];
   }
   for (i=0 ; i <= 10 ; i++){
      printf("%10d%12d            ", i, freq[i]);
      for (o=0; o<=freq[i];o++){
         printf("*");
      }
      printf("\n");
      if (freq[i] > freq[i+1]){
         mode = freq[i];
         rating = i;
      }
   }
   printf("The mode is the most frequent value.\n");
   printf("For this run the mode is %d which occured %d times", rating ,mode);
}
  • 1
    Why `rand() % 6` when you want a number between 1 and 9. It should be `rand() % 9 + 1`... – ShuklaSannidhya May 27 '13 at 17:49
  • Watch out for [modulo bias](http://stackoverflow.com/questions/10984974/why-do-people-say-there-is-modulo-bias-when-using-a-random-number-generator?lq=1). – Carl Norum May 27 '13 at 17:52
  • `frequency` array should be local to the `mode` function. You don't use it any where else. There's no point in declaring it in main and passing it to `mode`. Instead, declare it as a local to `mode`. – ShuklaSannidhya May 27 '13 at 18:05
  • BTW, you forgot to `#include ` for time(). – Jens May 27 '13 at 18:20

2 Answers2

3

C arrays are zero-based so valid indexes for

int response[SIZE];

are [0..SIZE-1]. Your loop writes to response[SIZE] which is beyond the end of memory assigned for response. This results in undefined behaviour.

If you're getting an infinite loop, it sounds as if the address of response[SIZE] is the same as the address of the loop counter i. (rand() % 6) +1 will be in the range [1..6] so the final iteration of the loop before exit will always reset i to a lower value.

You can fix this by changing your loop to exit one iteration sooner. i.e. Change

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

to

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

Note that your other functions all have similar bugs. All for loops should replace their <= exit conditions with <

simonc
  • 41,632
  • 12
  • 85
  • 103
1

You write past the end of your arrays when you access array[SIZE]. Any array declared

type_t array[SIZE];

doesn't have an element array[SIZE]. So all loops must be from 0 to < SIZE, not <= SIZE. This is known as an off-by-one error in computer literature. You're not the first and will not be the last, if it's any consolation :-)

Technically this invokes undefined behavior, of which an infinite loop is one way. But see my comment below for a wild-assed guess at what is really happening here.

Jens
  • 69,818
  • 15
  • 125
  • 179
  • Any reason for why does that result in infinite loop.? – ShuklaSannidhya May 27 '13 at 17:54
  • Very likely because in some function (mean(), median(), mode()) where you have `a[]` as the last argument, the first declared local variable is a loop variable `i` or `j`. Writing past `a[]` is then clobbering the loop variable. – Jens May 27 '13 at 17:56
  • That's not the only problem. Even fixing off-by-one won't stop infinite looping. There are many problems in the code. – P.P May 27 '13 at 18:06
  • @KingsIndian It stops being infinite here, but prints 6406162 asterisks, so yes, there is at least one more bug. – Jens May 27 '13 at 18:18