1

I completed a given code-example as a homework and it worked fine on my 64 Bit OS X device (compiled with gcc). But it won't execute on my Windows 8 64 Bit machine(compiled with MinGW - gcc). I used gcc sort.c -Wall -Wextra on both machines. Not execute means, that the programm stucks at line 64 in an infinity loop. Further I recognized that this happend after loop reaches 11 in line 64.

It also runs on Codepad (http://codepad.org/BoLhqtzv).

I tryed to use different ways of pointer arithmetics to access the arrays but none of them worked.

The programm sorts an array x of lengh n. In array x is like a bag. So there can appear one number multiple times. The function sort gets the lengh of the Array x, a pointer on the array x and the count of different numbers (10: from 0 to 9). The trick is that the Array muh knows how often which number appears in Array x. This works because the numbers in x are continous in N(atural Numbers).

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

#define M 10

/* This function generates an array of random integers in the range [0,M-1] of length n. */
int* random_array(const int n) {
  int *x;
  int i;

  x = (int*) malloc(n * sizeof(int));

  srand(time(NULL ));

  for (i = 0; i < n; i++) {
    x[i] = rand() % M;
  }

  return x;
}

/* print an array. */
void print_array(const int n, const int *x) {
  int i;

  printf("array: ");
  for (i = 0; i < n && i < 32; i++) {
    printf("%d ", x[i]);
  }
  if (n > 32) {
    printf("...");
  }
  printf("\n");
}

/* check if a given array is sorted in ascending order. */
void is_sorted(const int n, const int *x) {
  int i;

  for (i = 1; i < n; i++) {
    if (x[i - 1] > x[i]) {
      fprintf(stderr, "ERROR: Array is not sorted!\n");
      return;
    }
  }
  printf("Array is sorted!\n");
}

/* n is the length of the array x and m is the same m as on your exercise sheet.
 * In this case m is set to 10. */
void sort(const int n, int *x, int m) {
  /* allocates memory for an zero initialized array */
    int *muh = (int*) calloc(m, sizeof(int));
    int loop; //count variable

    /*counts each number in the array*/
    for(loop = 0; loop < n; loop++){
        muh[x[loop]]++;
    }

    /*Overrides x, Each number appears muh[loop] times at the beginning of line 65*/
    for(loop = 0; loop < n; loop++){
        for(; muh[loop] > 0; muh[loop]--) {
            *(x++) = loop;
       }
    }
}

int main() {
  int *x;
  int n;

  /* set length of the arrays */
  n = 1 << 5;

  /* get a random integer array of length n */
  x = random_array(n);

  /* print the unsorted array */
  print_array(n, x);

  printf("\n");
  printf("sorted array:\n");

  /* sort x by using sort, check if it is sorted and print it out */
  sort(n, x, M);
  is_sorted(n, x);
  print_array(n, x);

  return 0;
}
froehli
  • 904
  • 1
  • 11
  • 35

2 Answers2

6

Your muh has space for m elements, but

for(loop = 0; loop < n; loop++){
    for(; muh[loop] > 0; muh[loop]--) {
        *(x++) = loop;
   }
}

you loop through n. If n > m, you have undefined behaviour.

 * In this case m is set to 10. */

n = 1 << 5;

indicate that it bites you.

That it seems to work on some systems but not others, well, undefined behaviour does that for you.

Daniel Fischer
  • 181,706
  • 17
  • 308
  • 431
  • m ist the count of different numbers in n. If n = {0, 0, 0, 1, 1, 2} then muh ={3, 2, 1} and m = 3 – froehli Apr 26 '13 at 14:05
  • 1
    @froehli Well, I don't know why that is, but IIRC, MinGW uses the Windows C library, and its `malloc` may behave differently from glibc's, so that when you step outside the allocated chunk, on Linux you're just overwriting some unused memory, while on Windows, you overwrite something crucial. But to know for sure, one would need to run it under a good debugger - perhaps that isn't even enough. – Daniel Fischer Apr 26 '13 at 18:07
1

sort(n, x, M); -> sort(n, x, n);

loop < n and muh[0]..muh[9] (int *muh = (int*) calloc(m, sizeof(int)))

muh[loop] out of range when loop >= m

BLUEPIXY
  • 39,699
  • 7
  • 33
  • 70
  • the sort function is called right with sort(n, x, M) but I used the wrong variable in the loop condition. Correct version: http://codepad.org/lpAajc4v – froehli Apr 26 '13 at 17:55