Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Segmentation fault the second time printf is called

I'm writing a simple C program that opens a file, and reads each line into an array, where LISTS is the maximum number of lines in the file that I wish to read.

However, when MASTER_LIST is less than LISTS lines long, I get a segmentation fault on printf() the second time round, but not the first (I've commented to show where).

I'm a little confused by this behaviour, and I'm wondering what causes it and what I can do to circumvent it. Ideally I would stop reading when fgets finds the end of the file.

#define MASTER_LIST "master_list.txt"
#define LINE 64
#define LISTS 32

char **lists = malloc(LISTS * sizeof(char *));
int i; 
for (i = 0; i < LISTS; i++) {
    lists[i] = malloc(LINE * sizeof(char));
}

/*Open the file for reading.*/
FILE *fp = fopen(MASTER_LIST, "r");
if (fp != NULL) {
    /*Each line of the file, up to LISTS is read into lists.*/
    for (i = 0; i < LISTS; i++){

        lists[i] = fgets(lists[i], LINE, fp);
        /*NO SEGFAULT HERE*/ printf("Line Read: %s\n", lists[i]);                   
    }
}

/*print out each line*/
for(i = 0; i < LISTS; i++){
    printf("Are we segfaulting yet? %d\n", i);
    /*HERE I GET A SEGFAULT*/ printf("%s\n", lists[i]);
    printf("How about now? %d\n", i);       
}
like image 345
Bertholt Stutley Johnson Avatar asked Apr 03 '13 22:04

Bertholt Stutley Johnson


People also ask

Why does printf cause segmentation fault?

2 Answers. The main issue that causes a segmentation fault is line 22 - printf ("Name: %s \n", name); This is because you are printing a string, while name is 1 character. If I enter my name, only the first letter entered is actually written to the name variable.

Is segmentation fault a runtime error?

The segmentation error is one of the runtime error, that is caused because of the memory access violation, like accessing invalid array index, pointing some restricted address etc. In this article, we will see how to detect this type of error using the GDB tool.

What do you mean by segmentation fault?

Overview. A segmentation fault (aka segfault) is a common condition that causes programs to crash; they are often associated with a file named core . Segfaults are caused by a program trying to read or write an illegal memory location.

What happens during segmentation fault?

A segmentation fault occurs when a program attempts to access a memory location that it is not allowed to access, or attempts to access a memory location in a way that is not allowed (for example, attempting to write to a read-only location, or to overwrite part of the operating system).


1 Answers

fgets returns NULL if it fails to read any characters, which would happen if your file contains less than LISTS lines. Attempting to printf a NULL pointer is undefined behaviour.


This is a good time to remind ourselves that undefined behaviour really is undefined. It looks like the printf should crash the first time around. But, the C spec says nothing about what should happen, so your printf just prints (null) (many Linux libcs do this, for example).

Why does the second printf crash, then? It's because you used the pattern

printf("%s\n", lists[i]);

Many compilers will optimize this to

puts(lists[i]);

and on your system, puts does not check for a NULL pointer and so it segfaults.

Moral of the story? Don't ever rely on undefined behaviour, or even expect consistent results.

like image 189
nneonneo Avatar answered Sep 22 '22 00:09

nneonneo