0

I'm writing a code to split an array into 2 different ones, one with even numbers and one with odd numbers. I read the numbers from a file, put it all into an array, and get the split right. Here's the code where everything works:

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

int main(int argc, char** argv){
  FILE* fpointer;
  if (argc >= 2){
    fpointer = fopen(argv[1], "r");
  }else{
    printf("No filename or multiple file names given");
    return 0;
  }
  int numElem;
  fscanf (fpointer, "%d\n", &numElem);
  printf("Number of elements is %d\n", numElem);
  int* arr;
  int numEvens;
  int numOdds;
  arr = (int*) malloc(numElem*sizeof(int));
  for (int i = 0; i < numElem; i++){
    int temp;
    fscanf(fpointer, "%d", &temp);
    if(temp%2 == 0){
       numEvens++;
    }else{
      numOdds++;
    }
    arr[i] = temp;
  }
  fclose(fpointer);

printf("number of evens: %d \n number of odds: %d\n", numEvens, numOdds);
  //The array is now in "arr"
   int* evens;
   int* odds;
   evens = (int*) malloc(numEvens*sizeof(int));
   odds = (int*) malloc(numOdds*sizeof(int));
  int a = 0;
  int b = 0;
  for (int i=0; i < numElem; i++){
    printf("%d\n", arr[i]);
    if (arr[i]%2 == 0){
      evens[a] = arr[i];
      a++;
    }else{
      odds[b] = arr[i];
      b++;
    }
  }
  printf("EVENS: %d\n", numEvens);
  for (int i=0; i < numEvens; i++){
    printf("%d\n", evens[i]);
  }
  printf("ODDS: %d\n", numOdds);
  for (int i=0; i < numOdds; i++){
    printf("%d\n", odds[i]);
  }

Now I have a neat array with even numbers, and one with odd numbers. It outputs numEvens and numOdds correctly. Then I attempt to sort it:

  int temp;
  int x;
  int y;

  for (x = 0; x < numEvens-1; x++){
    for (y=x+1; y < numEvens; y++){
      if (evens[y] < evens[x]){
    temp = evens[y];
    evens[y] = evens[x];
    evens[x] = temp;
      }
    }
  }

  return 0;

}

The output before I add in the sort method is:

Number of elements is 8
number of evens: 5 
 number of odds: 3
25
10
1
99
4
2
8
10
EVENS: 5
10
4
2
8
10
ODDS: 3
25
1
7

And the new output becomes:

Number of elements is 8
number of evens: 32772 
 number of odds: 1764530596
25
10
1
99
4
2
8
10
EVENS: 32772
10
4
2
8
10
0
0
0
0
....

The 0's go on presumably for another 32,000 times until I abort. I'm trying my hand at C after coming from java so memory allocation is a new subject for me, but I'm assuming it has something to do with that. I just don't understand how variables can be changed by lines of code added in after they are declared and printed. I don't really need help with new sorting methods, I just want some pointers on what's happening here so I can fix the errors. Thanks in advance!

Scerzyy
  • 52
  • 10
  • 1
    Use a debugger and step through your sorting code. You're dealing with a very small number of items in the array, which means you can easily step through every single line and repetition to see what's going wrong. – Ken White Sep 28 '18 at 02:26
  • I'm currently teaching myself how to use the debugger, sadly not as easy as eclipse's was. But I posted this with hopes that someone would help out while I got this to work. – Scerzyy Sep 28 '18 at 02:36
  • I cannoot reproduce your error. I tried your code with the given inputs and everything seems to work. Either what you posted is different from what you compiled or your input file is different from what was given. Everything so far seems correct to me. – lightalchemist Sep 28 '18 at 02:41
  • Okay so I'm not crazy? I've been running through it line by line and can't find the error. I copied and pasted the code so that's exactly what was compiled, and I'm using the gcc compiler so the compiler itself works fine. The input file is a single integer, then on another line its multiple integers seperated by a tab. – Scerzyy Sep 28 '18 at 02:45
  • Your counters for `numEvens` and `numOdds` in your initial array pass are not initialized, therefore they contain indeterminate content and incrementing them, evaluating them, pretty much anything, invokes *undefined behavior*. Fyi, a decent compiler with pedantic warnings cranked to the limits will *very* likely warn you about this. – WhozCraig Sep 28 '18 at 02:45

1 Answers1

2
int numEvens;
int numOdds;

Initialize your variables:

int numEvens = 0;
int numOdds = 0;

... and don't cast the result of malloc()!

Swordfish
  • 12,971
  • 3
  • 21
  • 43
  • Doh! Yes did not see that! – lightalchemist Sep 28 '18 at 02:46
  • 1
    @lightalchemist Increase the warning level of your favourite compiler. – Swordfish Sep 28 '18 at 02:48
  • Awesome, so that's another thing that's different between C and Java, I'll definitely keep in mind that uninitialized variables is not the same as initializing to 0. I see the error there, but can I ask why I shouldn't cast the result of malloc? – Scerzyy Sep 28 '18 at 02:50
  • @Swordfish I compiled it with `gcc -Wall -Wextra test.c` without optimization flags so the warnings did not pop up. – lightalchemist Sep 28 '18 at 02:55
  • I did gcc -Wall -Werror -fsanitize=address. I'm pretty sure the last flag is what catches all my errors. – Scerzyy Sep 28 '18 at 02:56
  • @lightalchemist gcc seems to be really bad at reporting uninitialized variables: https://stackoverflow.com/questions/17705880/gcc-failing-to-warn-of-uninitialized-variable – Swordfish Sep 28 '18 at 03:03
  • @Swordfish Yep. Saw that post after seeing your answer. I was actually quite surprised gcc did not flag that without optimization because I'm pretty sure clang would have :(. Learned something new.. – lightalchemist Sep 28 '18 at 03:12