1

I created a small test program because the same issue was happening in my larger program. I am new to c, so maybe there is something obvious I'm missing. my program asks the user to input the amount of students and amount of courses they would like to add.. I then create an 2d array with the size set to the amount of students by the amount of courses. this 2d array causes a segmentation fault when I test the program only entering in 4 students and 4 courses, meaning there should only be 16 elements. I'm unsure why this causes a seg fault.

int registry[][] is the array in question

I've tested the program with and without the 2d array and it works perfectly fine without it.

int main (void) {

    int numOfStds;
    int numOfCrs;
    int stdNum;

    printf("How many students would you like to register:");
    scanf("%d", &numOfStds );

    printf("How many courses are in the program?:");
    scanf("%d", &numOfCrs);

    int students[numOfStds];
    char courses[numOfCrs][8];
    for(int i; i < numOfStds; i++){
        printf("Please enter student %d's number:", i);
        scanf("%d", &stdNum);
        students[i] = stdNum;
    }

    for(int i; i < numOfCrs; i++){
        printf("Please enter course %d's code (must be 7 characters long):", i);
        scanf("%s", courses[i]);

    }
    int registry[numOfStds][numOfCrs];

    for(int i; i< numOfCrs; i++){
        printf("%s\n", courses[i]);
    }

    for(int i; i < numOfStds; i++){
        printf("%d\n", students[i]);
    }
}
MCkea444
  • 15
  • 3
  • What do you think `scanf("%d/n", &stdNum);` is doing? Is there really a `"/n"` that is input? Get rid of `"/n"` and ***validate*** each input, e.g. `if (scanf ("%d", &numOfStds) != 1) { fputs ("error: invalid integer input.\n", stderr); return 1; }` – David C. Rankin Oct 03 '19 at 21:45
  • @DavidC.Rankin I removed all "\n" and there is still a seg fault. when 4 students and 4 courses is entered, it says please enter student -2145812148's number: and then gives me a seg fault. – MCkea444 Oct 03 '19 at 21:54
  • `for(int i; i < numOfCrs; i++)` what is the value of `i` on the first iteration?? – David C. Rankin Oct 03 '19 at 21:56

2 Answers2

0

In all of your for loops, you are using the index variable i uninitialized. This can cause undefined behavior. Since the behavior is undefined, the presence or absence of the registry array may alter the behavior.

You should initialize i in each for loop like this:

    for(int i = 0; i < numOfStds; i++){

I will also echo the concerns raised in David's answer. If you call a function that returns a status, you should always check the status to make sure it is what you expect. It is always better to handle errors as soon as they occur. Your code as written assumes no errors in the input, which is not valid in the general case. This is not a theoretical problem. Practical applications always have the possibility of encountering invalid or malformed input.

jxh
  • 69,070
  • 8
  • 110
  • 193
0

As noted in my comments, you have two primary problems. The scanf ("%d/n", ...) format string is just wrong unless the user is actually entering a "/n" after each input and second, your loop variable is uninitialized in each for loop.

But even more troubling is you fail to validate the return of scanf on each call, so a single mistyped character can cause your integer conversion to fail silently and you proceed forward as if nothing is wrong. For example, if reaching for the 3 your user accidentally hits 'e', then a matching-failure occurs, character extraction from stdin stops at that point, and if you are looping collecting integer input, you have just spun off into an infinite loop.

Always Validate Every Input

It takes nothing more than simple validation to save yourself from yourself. To validate you input you can do:

    printf("How many students would you like to register: ");
    if (scanf ("%d", &numOfStds) != 1) {
        fputs ("error: invalid integer input - numOfStds.\n", stderr);
        return 1;
    }

and for another example:

    for(int i = 0; i < numOfStds; i++){
        printf ("Please enter student %d's number: ", i+1);
        if (scanf("%d", &stdNum) != 1) {
            fputs ("error: invalid integer input - stdNum.\n", stderr);
            return 1;
        }
        students[i] = stdNum;
    }

Putting it together in a full example, and then outputting the collected values you can do:

#include <stdio.h>

int main (void) {

    int numOfStds;
    int numOfCrs;
    int stdNum;

    printf("How many students would you like to register: ");
    if (scanf ("%d", &numOfStds) != 1) {
        fputs ("error: invalid integer input - numOfStds.\n", stderr);
        return 1;
    }

    printf("How many courses are in the program?: ");
    if (scanf ("%d", &numOfCrs) != 1) {
        fputs ("error: invalid integer input - numOfCrs.\n", stderr);
        return 1;
    }

    int students[numOfStds];
    char courses[numOfCrs][8];

    for(int i = 0; i < numOfStds; i++){
        printf ("Please enter student %d's number: ", i+1);
        if (scanf("%d", &stdNum) != 1) {
            fputs ("error: invalid integer input - stdNum.\n", stderr);
            return 1;
        }
        students[i] = stdNum;
    }

    for(int i = 0; i < numOfCrs; i++){
        printf("Please enter course %d's code (must be 7 characters long): ",
                i+1);
        if (scanf ("%7s", courses[i]) != 1) {
            fputs ("error: invalid integer input - numOfCrs.\n", stderr);
            return 1;
        }
    }

    /* example output */
    // int registry[numOfStds][numOfCrs];
    puts ("\nStudents:");
    for (int i = 0; i < numOfStds; i++)
        printf ("student: %d\n", students[i]);
    puts ("\nCourses:");
    for (int i = 0; i < numOfCrs; i++)
        printf ("course: %s\n", courses[i]);
}

(note: above the protection of your array bounds with if (scanf ("%7s", courses[i]) != 1), if you fail to include the 7 as a field-width modifier, your user can enter as many characters as they wish resulting in Undefined Behavior)

Example Use/Output

$ ./bin/numofstds
How many students would you like to register: 3
How many courses are in the program?: 2
Please enter student 1's number: 301
Please enter student 2's number: 302
Please enter student 3's number: 303
Please enter course 1's code (must be 7 characters long): abcdefg
Please enter course 2's code (must be 7 characters long): bcdefgh

Students:
student: 301
student: 302
student: 303

Courses:
course: abcdefg
course: bcdefgh

Look things over and let me know if you have further questions.

David C. Rankin
  • 81,885
  • 6
  • 58
  • 85