-2

So I've completed my latest assignment last night in Dev C++, which is what we are required to create it in. Got it working flawlessly, compiles great, runs great, everything is fine. However, we have to run our program through 'MobaXTerm' and through a VPN, using our University's system that they use to grade on. I tried to run it and I get an error, 'segmentation fault'. That was the first time I heard of the error so I researched it. In most cases, it's putting the wrong variable in a 'for loop' but I checked my loops 50 times, it works. I assume it has something to do with my 2D array, maybe going out of bounds, but I debugged, and from what I can tell, it doesn't escape the size that I assigned for it.

I don't exactly just want to paste my whole program in here but I'll give a few snippets and maybe someone could try to tell me what might possibly be the issue. I just don't really understand how it runs fine in one and not the other.

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

#define ROWS 12
#define COLS 8

void makeArray(FILE*, int [][COLS]);
int getScore(int [][COLS], int, int);
int getMonthMax(int [][COLS], int);
int getYearMax(int [][COLS]);
float getMonthAvg(int [][COLS], int);
float getYearAvg(int [][COLS]);
int toursMissed(int [][COLS]);
void displayMenu();
int processRequest(int [][COLS], int);
void printArray(int [][COLS]);

int main(){
int scoresArray[ROWS][COLS];
int choice, constant = 0;
FILE *scoreFileptr;
scoreFileptr = fopen("scores.txt", "r");
if (scoreFileptr == NULL)
    printf("The file isn't opening");
makeArray(scoreFileptr, scoresArray);

while(constant == 0){
  displayMenu();
  scanf("%d", &choice);
  processRequest(scoresArray, choice);
}

fclose(scoreFileptr);
}

Here's a function:

void makeArray(FILE *scoreFileptr, int scoresArray[][COLS]){
int i, j, filler = 0;

for(i = 0; i < ROWS; i++){
    for(j = 0; j < COLS; j++){
        fscanf(scoreFileptr, "%d", &filler);
        if(filler == 999){
            break;
        }
        scoresArray[i][j] = filler;

    }
  }
}

Here's another function:

int processRequest(int scoresArray[][COLS], int choice){
int month = 0, tourNum = 0;

switch(choice){

    case 1: 
        printf("Please enter the month and the game\n");
        scanf("%d %d", &month, &tourNum);
        printf("The score for tournament %d is %d\n\n",tourNum, getScore(scoresArray, month, tourNum));

    break;

    case 2:     
        printf("Please enter the month\n");
        scanf("%d", &month);
        printf("The max score in month %d is %d\n\n", month, getMonthMax(scoresArray, month));
    break;

    case 3:
        printf("Please enter the month\n");
        scanf("%d", &month);
        printf("The average score for month %d is %.2f\n\n", month, getMonthAvg(scoresArray, month));
    break;

    case 4:
        printf("The max score for the year is %d\n\n", getYearMax(scoresArray));
    break;

    case 5:
        printf("The average score for the year is %.2f\n\n", getYearAvg(scoresArray));
    break;

    case 6:
        printf("The number of tournaments missed for the year is %d\n\n", toursMissed(scoresArray));
    break;

    case 7:
        printf("The scores for the year are:\n");
        printArray(scoresArray);
    break;

    case 0: printf("Thank you! Goodbye");
    exit(0);
    break;

    default:
        printf("Please enter one of the options listed\n\n");

}
return 0;

}

Do you think it's the way I'm passing the array to the functions? That's the only way I can think of. But then why would it work in the Dev C++ compiler? I'm stumped.

Edit: The problem seems to be in the 'makeArray' function. I took out the function call for it in main and it runs now. Just got to figure out what's causing it.

Edit 2: After going through the function line by line, they problem seems to be the 'fscanf' line in the makeArray function. Thank you all for pointing me in the right direction!

2 Answers2

2

Since the whole code is not available, I'll tell you the cause and what to look for, but I can't provide an exact answer.

In C there is a thing called undefined behavior. What this means is that the standard does not guarantee what happens in that case. It may work, it may fail at runtime, basically anything can happen.

The most common undefined behavior errors that are encountered are memory related errors. For example, assume the following code snippet:

int a[10];
a[10] = 2;

I access an element outside the allocated region of the array a. This is undefined behavour according to the standard, so there is no hint about what can happen. In practice, there are usually 2 outcomes: it can run almost fine or it can produce a segmentation fault, depending on the compiler.

Why it depends on the compiler? Well, this kind of code goes into the stack memory area, which is managed by the compiler. In some cases, overwriting the memory location after the array might not overwrite an important memory region of the program, and the program can finish executing. In other cases, the compiler decides to put some important data just after the array (like a stack pointer), which, if overwritten, makes the program to crash. Also, there might be some protected memory region after that array or you may corrupt the value of another variable you plan to use.

(I described just some common possible outcomes of this. There are other problems this type of errors can cause).

It just happens that the code compiled with Dev C++ can run with this error. Note that this is not a good thing by no means - undefined behaviors should be avoided at any cost.

As I said, it's pretty hard to say where is actually the problem. Just a few hints for debugging: try to remove some parts of the code until it works, then add piece by piece and try to locate the line(s) where the error occurs.

P.S. Also, make sure you have the input file available.

Paul92
  • 8,827
  • 1
  • 23
  • 37
  • Thank you for the assistance. I made the function call for 'makeArray' that is in main a comment and the code ran. So I'm gonna go through the function and see the problem. I think it has to do with the way I used the 2D array I defined in main as a parameter in the function. Thanks again! – Kyle Steward Jul 24 '16 at 18:54
0
#include <stdio.h>
#include <stdlib.h>

#define ROWS 12
#define COLS 8

void makeArray(FILE* scoreFileptr,int (*scoresArray)[COLS]);

int main(){
  int scoresArray[ROWS][COLS];
  int choice, constant = 0;

  FILE* scoreFileptr = fopen("scores.txt", "r");
  if (scoreFileptr == NULL){
    printf("The file isn't opening\n");
  }else{ printf("opened\n");}   
  makeArray(scoreFileptr,scoresArray);
  //printf("%d\n",scoresArray[0][3]); test
  fclose(scoreFileptr);

}


void makeArray(FILE* scoreFileptr,int (*scoresArray)[COLS]){
  int i, j, filler = 0;

  for(i = 0; i < ROWS; i++){
    for(j = 0; j < COLS; j++){
      fscanf(scoreFileptr, "%d", &filler);
      if(filler == 999){
         break;
      }
      scoresArray[i][j] = filler;

    }
  }
}

This is the piece of your code that I have modified a bit and it's working (compiled with gcc). Hope it can help. As you can see, since your function is void I passes the address of the 2D.

mik1904
  • 1,335
  • 9
  • 18