1

When i run the following code i got an error;

Program received signal SIGSEGV, Segmentation fault. 0x00007ffff7a74402 in __GI__IO_vfscanf () from /lib64/libc.so.6 Missing separate debuginfos, use: debuginfo-install glibc-2.17-78.el7.x86_64

i run my code using gcc warnings enable(-Wall) and debug it step by step. The error is in the line for getting multi-dimensional array elements. When i reach at the step for grades[1][2], it says cannot access memory at address 0x00007ffff7a74402. What is the wrong in the code?

 #include <stdio.h>

    //_________Prototypes________//

    int calcHighest(int grades[][4],int);
    int calcLowest(int grades[][4],int);
    int calcAverage(int grades[][4],int);

    int main (void){

      int funcSelection,nbOfStudent;
      int grades[nbOfStudent][4];
      int i,j;

      scanf("%d",&funcSelection);

     //check is one 1,2,3 and a number
      if(funcSelection <= 0 || funcSelection > 3){
        printf("Invalid Input.Please enter 1,2 or 3\n");
          return 1;
      }

      scanf("%d",&nbOfStudent);
     //check if it is positive and a number
      if(nbOfStudent <= 0){
        printf("Please enter a non-negative number\n");
         return 1;
      }

      for(i = 0;i < nbOfStudent;i++){
         for(j =0;j<4;j++){
           scanf("%d",&grades[i][j]);
         }
       }

      for(i = 0;i < nbOfStudent;i++){
         for(j =0;j<4;j++){
           scanf("%d",&grades[i][j]);
         }
       }

      if(funcSelection == 1){

        printf("%d\n",calcLowest(grades,nbOfStudent));
      }else if(funcSelection == 2){
        printf("%d\n",calcHighest(grades,nbOfStudent));
      }else{
        printf("%d\n",calcAverage(grades,nbOfStudent));
      }
      return 0;

    }
Emel Uras
  • 394
  • 2
  • 13
  • 3
    `int grades[nbOfStudent][4];` as yourself what the value of `nbOfStudent` is *when that declaration is encountered*. Hint: `scanf`-ing that variable later doesn't change what came before. – WhozCraig Mar 16 '16 at 03:46
  • Then,how can i create array with dynamic size? – Emel Uras Mar 16 '16 at 03:51
  • see my question: [How can I work with dynamically-allocated arbitrary-dimensional arrays?](http://stackoverflow.com/questions/30023867/how-can-i-work-with-dynamically-allocated-arbitrary-dimensional-arrays) My answer shows a 'clever' way. The highest-voted answer shows a typical C99 way. – luser droog Mar 16 '16 at 04:43

3 Answers3

4

This is where the problem lies:

int funcSelection,nbOfStudent;
int grades[nbOfStudent][4];

Think what's the value of nbOfStudent is when grades is defined. Since nbOfStudent is uninitialized, anything could be its value and using an uninitialized variable invokes Undefined Behavior.

Fix the problem by moving

int grades[nbOfStudent][4];

after

scanf("%d",&nbOfStudent);
//check if it is positive and a number
if(nbOfStudent <= 0){
  printf("Please enter a non-negative number\n");
 return 1;
}
Spikatrix
  • 20,225
  • 7
  • 37
  • 83
2
int funcSelection,nbOfStudent;
      int grades[nbOfStudent][4]; //problem leads to undefined behaviour
      int i,j;

nbofStudent doesnot contain any value its a garbage vale and its lead to undefined behaviour.

Solution:

populate the value nbofStudent before defining an array. in your case scanf for nbofStudent before declaring an array and check for the validity of the variable.

scanf("%d",&nbOfStudent);
     //check if it is positive and a number
      if(nbOfStudent <= 0){
        printf("Please enter a non-negative number\n");
         return 1;
      }

Variable should be defined after these instructions. so silly to mention statements execute sequentially.

Dilip Kumar
  • 1,736
  • 11
  • 22
0

the posted code contains several errors and oversights, including:

  1. fails to prompt user for number of students
  2. contains 'magic' numbers like 3 and 4
  3. fails to prompt user for grades for each student
  4. fails to prompt user for which 'function' to be performed
  5. uses int for values that can only be positive

Here is my proposed code

#include <stdio.h>
#include <stdlib.h>  // exit(), EXIT_FAILURE

#define NUM_GRADES (4)
#define MAX_FUNC   (3)

//_________Prototypes________//
int calcHighest(int grades[][ NUM_GRADES ], size_t);
int calcLowest( int grades[][ NUM_GRADES ], size_t);
int calcAverage(int grades[][ NUM_GRADES ], size_t);

int main (void)
{

    printf( "Enter number of Students: ");
    size_t nbOfStudent;
    if( 1 != scanf("%lu",&nbOfStudent) )
    { // then scanf for number of students failed
        perror( "scanf for number students failed");
        exit( EXIT_FAILURE );
    }

    // implied else, scanf successful

    //only declare array 'grades[][]' after knowing number of students
    int grades[nbOfStudent][ NUM_GRADES ];

    printf( "Enter %d grades for each of the %lu students: ", NUM_GRADES, nbOfStudent);
    for(size_t i = 0;i < nbOfStudent;i++)
    {
        for(size_t j=0; j<NUM_GRADES; j++)
        {
            scanf("%d",&grades[i][j]);
        }
    }


    printf( "1: calculate lowest student grade\n");
    printf( "2: calculate highest student grade\n");
    printf( "3: calculate average student grade\n");
    printf( "Enter Selection: ");
    size_t funcSelection;
    scanf("%lu",&funcSelection);
    if( 1 != scanf("%lu",&funcSelection) )
    { // then scanf for function selection failed
        perror( "scanf for function selection failed");
        exit( EXIT_FAILURE );
    }

    // implied else, scanf successful

    switch( funcSelection )
    {
        case 1:
            printf("%d\n",calcLowest(grades,nbOfStudent));
            break;

        case 2:
            printf("%d\n",calcHighest(grades,nbOfStudent));
            break;

        case 3:
            printf("%d\n",calcAverage(grades,nbOfStudent));
            break;

        case 0: // fall through
        default:
            printf("Invalid Input.Please enter 1,2 or 3\n");
            break;
    } // end switch

    return 0;
} // end function: main
user3629249
  • 16,402
  • 1
  • 16
  • 17