user3437503
user3437503

Reputation: 169

fclose() causes Segmentation Fault

I've been trying simple file handling in C and I wanted to make sure that the file can be accessed tried using this

#include<stdio.h>

main()
{
    CheckFile();
}

int CheckFile()
{
    int checkfile=0;

    FILE *fp1;
    fp1 = fopen("users.sav","r");

    if(fp1==NULL)
    {
        fopen("users.sav","w");
        fclose(fp1);
    }   
    if(checkfile!=0)printf("\nERROR ACCESSING FILE!\nNow exiting program with exit code: %d\n",checkfile);exit(1);
    return 0;
}

then it displays

Segmentation fault (core dumped)

but it doesn't segfault if the file already exists beforehand (e.g. when i created it manually or when i run the program the second time)

Please help. I need this for our final project due in a week and I haven't gotten the hang of files and pointers yet.

I'm using "gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1"

P.s

I saw this in another question

There's no guarantee in your original code that the fopen is actually working, in which case it will return NULL and the fclose will not be defined behaviour.

So how exactly do I check if it worked?

Upvotes: 13

Views: 28419

Answers (5)

Jabberwocky
Jabberwocky

Reputation: 50775

That's normal, when you call fclose(fp1) when fp1 is NULL.

BTW

fopen("users.sav","w");

is useless because you don't assign the return value to a file pointer. That means the users.sav file will be opened for writing, but you will never be able to write anything in it .

Upvotes: 8

user2591612
user2591612

Reputation:

fopen returns a FILE pointer. It will return NULL and set the global errno to indicate the error. If you want to check the errno, you have to check if after you check if fopen returned NULL.

if (fp1 == NULL)
{
    printf("fopen failed, errno = %d\n", errno);
}

Otherwise, you may get an errno from something else, not necessarily your fopen call. Also include errno.h. You also don't need to call fopen("users.sav","w"); again. You aren't reassigning the pointer nor checking it again.

I don't see a reason to call fclose here since if fopen returns NULL, there isn't anything to close. That is probably the reason for your seg fault. You are trying to close a null pointer. More information on fopen failures.

Another comment on your code. If you are going to return an int from CheckFile, it should probably not be 0 on fail. I would return -1 to indicate an error. Better yet, you could return the global errno. Also, main should be int main() and you should return 0; at the end. I don't particularly care for your naming scheme of CheckFile. In C, check_file or camelCase of checkFile would be better.

In CheckFile, your one line if statement could be formatted and work more properly if you formatted it on multiple lines. It doesn't do what you think it does currently:

if(checkfile!=0)
{
   printf("\nERROR ACCESSING FILE!\nNow exiting program with exit code: %d\n", checkfile);
   exit(1);
}

Also, checkfile is never set anywhere in your code.. other than zero. So the code in the if statement will not execute, period.

Upvotes: 5

Jabberwocky
Jabberwocky

Reputation: 50775

Another unrelated problem:

This line is probably not what you want:

if(checkfile!=0)printf("\nERROR ACCESSING FILE!\nNow exiting program with exit code: %d\n",checkfile);exit(1);

If we write it correctly formatted the error becomes obvious:

if (checkfile != 0)
  printf("\nERROR ACCESSING FILE!\nNow exiting program with exit code: %d\n",checkfile);

exit(1);
return 0 ;

Actually we will get to exit(1) even if checkfile is zero.

You probably want this:

if (checkfile != 0)
{
  printf("\nERROR ACCESSING FILE!\nNow exiting program with exit code: %d\n",checkfile);
  exit(1); 
}

return 0 ;

Conclusion: format your code correctly and many errors will suddenly look obvious.

Upvotes: 0

mtripp100
mtripp100

Reputation: 241

I'm not really sure what you're trying to do, but the immediate problem is here:

if(fp1==NULL)
   fclose(fp1);

After asserting that fp1 is NULL, you're trying to call close on the null pointer, which will cause a segmentation fault.

If all you want to do is verify that the file exists, try something like What's the best way to check if a file exists in C? (cross platform)

Upvotes: 3

ajay
ajay

Reputation: 9680

The man page of fclose says -

The behaviour of fclose() is undefined if the stream parameter is an illegal pointer, or is a descriptor already passed to a previous invocation of fclose().

The error is in the if block in your code.

if(fp1==NULL)
{
    fopen("users.sav","w");
    fclose(fp1);  // passing NULL to fclose invokes undefined behaviour
}   

Upvotes: 0

Related Questions