chilliefiber
chilliefiber

Reputation: 651

Segmentation fault traversing a text file

I have this code, it's supposed to read a text file character by character and then do something with it, but the code keeps on segfaulting at line 6.

#include <stdio.h>

int main(void) 
{
    printf("a\n");
    FILE* fp = fopen("~/pset5/dictionaries/small", "r");
    for (int a = fgetc(fp); a != EOF; a = fgetc(fp))
    {
        printf("b\n");        
    }
    return 0;
}

Something weird is definitely happening, because it doesn't even print "a\n" to the terminal, even tough the call to printf is before the error. I've run the program with gdb, and this is where it fails.

6           for (int a = fgetc(fp); a != EOF; a = fgetc(fp))
(gdb) n

Program received signal SIGSEGV, Segmentation fault.
_IO_getc (fp=0x0) at getc.c:38
38      getc.c: No such file or directory.

I've also ran it with valgrind as in valgrind --leak-check=full ./test, with test being the name of the executable, and this is the relevant error message:

==7568== Invalid read of size 4
==7568==    at 0x4EA8A21: getc (getc.c:38)
==7568==    by 0x4005ED: main (test.c:6)
==7568==  Address 0x0 is not stack'd, malloc'd or (recently) free'd
==7568== 
==7568== 
==7568== Process terminating with default action of signal 11 (SIGSEGV)
==7568==  Access not within mapped region at address 0x0

I'm really at a loss here, can someone explain what's going on with this segmentation fault, and why the hell isn't the first call to printf printing anything?

Upvotes: 2

Views: 250

Answers (2)

melpomene
melpomene

Reputation: 85887

As the debugger says (fp=0x0), you're calling fgetc with a null pointer. This is what causes the crash.

fp is null because the fopen call failed. You need to check for errors.

Opening the file fails because most likely you do not have a directory called ~. Recall that expanding ~ to your home directory is done by the shell when you type a command. fopen only takes real filenames.

Upvotes: 5

Yunnosch
Yunnosch

Reputation: 26763

You forgot to check the return value of fopen() against NULL, which indicates an error while attempting to open the file.

Your for loop busily uses a NULL pointer, hence you get segfault.

Check the global variable errno to find out more about what exactly went wrong in your case.

Upvotes: 1

Related Questions