Home > Blockchain >  Why does this fgets function give me a segmentation fault?
Why does this fgets function give me a segmentation fault?

Time:11-28

This function below terminates and gives a segmentation fault at the fgets statement and I have no idea why:

const char* display_exp(FILE* fp){

    char maxstr[50];
    char* temp;
    char* exp;
    fgets(maxstr,sizeof(maxstr),fp);

    exp = (char*)calloc(strlen(maxstr),sizeof(char));
    temp=maxstr;

    free(temp);

    printf("%s",exp);

    return exp;
}

CodePudding user response:

You may not call the function free for an array with automatic storage duration as you are trying to do

char maxstr[50];

//...

temp=maxstr;

free(temp);

You may call the function free only for pointers that point to a dynamically allocated memory or for null pointers.

Also this call

printf("%s",exp);

does not make a great sense because the dynamically allocated array pointed to by the pointer exp contains an empty string

exp = (char*)calloc(strlen(maxstr),sizeof(char));

It seems you mean something like the following

const char * display_exp(FILE *fp)
{
    char maxstr[50] = { 0 };

    char *exp = NULL;

    if ( fgets(maxstr,sizeof(maxstr),fp) != NULL )
    {
        maxstr[ strcspn( maxstr, "\n" ) ] = '\0';

        char *exp = malloc( strlen(maxstr)   1 );
        if ( exp != NULL ) strcpy( exp, maxstr );
    }

    return exp;
}

CodePudding user response:

There are multiple problems in your code:

  • you do not test if fgets() was successful, leading to undefined behavior at end of file.

  • you must allocate one extra byte for the null terminator. Either use exp = calloc(strlen(maxstr) 1, 1); and check for memory allocation failure or better use exp = strdup(maxstr);.

  • assigning temp = maxstr; does not copy the string, you should use strcpy(exp, maxstr), or use strdup() that performs both allocation and string copying.

  • free(temp); attempts to free a local array, causing undefined behavior. The local array does not need to be freed, its space will be reclaimed automatically when the function returns, hence the name automatic storage.

  • return exp returns a pointer to an empty string as you did not copy the string read into maxstr into the allocated array.

Here is a modified version:

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

char *display_exp(FILE *fp) {
    char maxstr[50];

    if (fgets(maxstr, sizeof(maxstr), fp)) {
        // return an allocated copy of the line read from the user
        // if the line read has fewer than 49 characters and ends with
        // a newline, this newline is present in the string. You may
        // want to remove it by uncommenting this:
        //maxstr[strcspn(maxstr, "\n")] = '\0';
        return strdup(maxstr);
    } else {
        // fgets encountered a read error or the end of file.
        return NULL;
    }
}
  • Related