-2

I am trying to write this c program in Linux but when I run the program it executes half of the code and then bash shows this message "Segmentation fault (core dumped)" here is the code:

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

int main()
{   
    char stName[30];
    int info[3];
    int showinfo()
   {
    printf("The name of the student is %s\n",stName);
    printf("The age of the student is %d",info[0]);
    int i = 1;
    while(i<4)
    {
     printf("The marks in subject %d is %d",i,info[i]);
     i++;
    }
   }
    int getinfo()
   {
    printf("Enter name of the student: ");
    gets(stName);
    printf("enter the age of the student %s : ",stName);
    gets(info[0]);
    for(int i=1;i<4;i++)
    {
     printf("Enter the marks in subjet %d",i);
     gets(info[i]);
    }
    return 0;
   }
    getinfo();
    showinfo();
    
}

The output is like this:

Enter name of the student: Keshav
enter the age of the student Keshav : 20
Segmentation fault (core dumped)
  • 1
    since the array starts at 0 and has a length of 3 the last index wiill be 2. But you try to access index 3. That is your out of bounds I guess. – The Fool Aug 06 '20 at 07:01
  • @TheFool execution does not reach that line, otherwise `Enter the marks...` would be printed twice – mangusta Aug 06 '20 at 07:03
  • You shouldn't use `gets` (never be used) to read non-string types. Also the type is wrong, `gets` takes `char *` as the argument type. And C doesn't support using nested functions – Inian Aug 06 '20 at 07:05
  • 1
    It isn't valid C -- C doesn't permit nested functions. Always compile with *warnings enabled*, and **do not** accept code until it *compiles without warning*. To enable warnings add `-Wall -Wextra -pedantic` to your `gcc/clang` compile string (also consider adding `-Wshadow` to warn on shadowed variables). For **VS** (`cl.exe` on windows), use `/W3`. All other compilers will have similar options. Read and understand each warning -- then go fix it. They will identify any problems, and the exact line on which they occur. You can learn a lot by listening to what your compiler is telling you. – David C. Rankin Aug 06 '20 at 07:05
  • long story short, `gets` tries to write the input string into address pointed by `info[0]` which has not been initialized and thus contains garbage value – mangusta Aug 06 '20 at 07:09
  • [Why gets() is so dangerous it should never be used!](https://stackoverflow.com/questions/1694036/why-is-the-gets-function-dangerous-why-should-it-not-be-used) – David C. Rankin Aug 06 '20 at 07:09
  • @hyde I mean with a given set of enabled warnings, which allowed a successful compilation in this case – mangusta Aug 06 '20 at 07:23

1 Answers1

2

You have a great number of small problems. First "ISO C forbids nested functions", you should declare/define void showinfo() and char *getinto() above main(), not in it. Next, you must ensure when you loop, you do not attempt to write beyond the bounds of your arrays. Next, see: Why gets() is so dangerous it should never be used! It is so insecure and so prone to exploit by buffer-overrun it has been completely removed for the C11 library.

When writing showinfo(), it being nothing but an output routine, there is no need to have that function return a value. Change the return type to void to make that clear. Since you are now declaring the functions outside of main(), you will need to pass the variables needed in that function as parameters, e.g.

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

#define MAXC 128   /* if you need a constant, #define one (or more) */
#define NFOC   4

void showinfo (const char *stName, int *info)
{
    printf ("\nThe name of the student is %s\n"
            "The age of the student is %d\n\n", stName, info[0]);
    
    for (int i = 1; i < NFOC; i++)
        printf ("  The marks in subject %2d is %2d\n", i, info[i]);
}

(note: you only need a single printf() call to output both lines of text. Adjacent literal character string are concatenated during compilation)

and for getinfo(),

char *getinfo (char *stName, int *info)
{
    fputs ("Enter name of the student: ", stdout);
    if (fgets (stName, MAXC, stdin) == NULL)
        return NULL;
    stName[strcspn (stName, "\r\n")] = 0;   /* trim trailing \n from end of stName */
    
    printf ("enter the age of the student %s  : ", stName);
    if (scanf ("%d", &info[0]) != 1)
        return NULL;
    
    for (int i = 1; i < NFOC; i++) {
        printf ("Enter the marks in subjet %d : ", i);
        if (scanf ("%d", &info[i]) != 1)
            return NULL;
    }
    return stName;
}

Above the stName arrays along with the info array are passes as parameters to the function, as well as to showinfo() above. Here the return of stName is for convenience allowing you to use the function within the printf variable list if desired. It returns NULL to indicate failure in collecting the input.

main() now simplifies to:

int main (void)
{
    char stName[MAXC];
    int info[NFOC];
    
    getinfo (stName, info);
    showinfo (stName, info);
}

Example Use/Output

Running your program and providing input when prompted, you would receive the following output:

$ ./bin/nested
Enter name of the student: John Q. Student
enter the age of the student John Q. Student  : 21
Enter the marks in subjet 1 : 88
Enter the marks in subjet 2 : 87
Enter the marks in subjet 3 : 92

The name of the student is John Q. Student
The age of the student is 21

  The marks in subject  1 is 88
  The marks in subject  2 is 87
  The marks in subject  3 is 92

Enable Warnings

Always compile with warnings enabled, and do not accept code until it compiles without warning. To enable warnings add -Wall -Wextra -pedantic to your gcc/clang compile string (also consider adding -Wshadow to warn on shadowed variables). For VS (cl.exe on windows), use /W3. All other compilers will have similar options. Read and understand each warning -- then go fix it. They will identify any problems, and the exact line on which they occur. You can learn a lot by listening to what your compiler is telling you.

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

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