简体   繁体   中英

Stack smashing detected with fgets() function in C

I got this code:

while(!feof(fp))
{
   fgets(line,20,fp);
   puts(line);
}

fp is this file:

prova1
prova2
prova3prova4
prova5

The fact is: if the count parameter of the fgets function it's a lower number than 10 it works everything ok, but if it's greater it gives me a stack smashing detected error.

I think it's because I'm trying to read after EOF, but why when I'm trying to read just after it works (like 8 characters per line) but when I put a count parameter of like 20 it gives me an error?

NB: the last line "prova5" is formed by 6 characters plus the '\\0' I think, so 7. Why with 8 it's ok and it's not with 20?

EDIT: I'm sorry, I forgot to include this declaration:

char line[] = " ";

Why with 8 it's ok and it's not with 20?

This suggests the possibility that line has not been defined with enough space for containing 20 char . To be in line with your code snippet, line should be defined as:

char line[20];  

Depending on your actual definition of line , you could be seeing results of buffer overflow . The reason it seems to work, then not work is undefined behavior , which means any behavior is possible, and at unexpected times.

Also, you should consider replacing while(!feof(fp)) with while(fgets(line, 20, fp)) which checks the return of fgets as a test, and exits upon seeing NULL . feof() ( is broken )

while(fgets(line, 20, fp))//will exit loop upon a null return
{
   //do something with line;
   puts(line);
}  

EDIT to address clarification in comment:

If you declared line as a pointer:

char *line;

Then before using it in the rest of your code the pointer needs to be given an address with corresponding memory sufficient to contain 20 char . This statement (and test to ensure memory was allocated) will do both:

line = calloc(20, 1);
if(line)
{
    //use line as described above  

EDIT 2 to address new information in OP.

Since line was defined as (edited into OP later)

char line[] = " ";

It has room for only 1 character. This will cause buffer overflow , and explains the inconsistent behavior that was observed (and written about in the post.)

The suggested way to define line to support what the code shown in your post needs is:

char line[20] = {0}; //space for 20 char, initialized to all zeros.

This, along with the other suggestions about replacing feof with fgets will improve the performance you see, and eliminate undefined behavior due to buffer overflow

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM