[英]Stack smashing detected with fgets() function in C
我得到了这个代码:
while(!feof(fp))
{
fgets(line,20,fp);
puts(line);
}
fp
是这个文件:
prova1
prova2
prova3prova4
prova5
事实是:如果 fgets 函数的 count 参数小于 10,则一切正常,但如果它更大,则会出现stack smashing detected
错误。
我认为这是因为我试图在 EOF 之后阅读,但是为什么当我试图在它工作后立即阅读时(例如每行 8 个字符),但是当我将计数参数设置为 20 时,它会给我一个错误?
注意:最后一行“prova5”由 6 个字符加上 '\\0' 组成,我认为是 7。为什么 8 可以,而 20 不行?
编辑:对不起,我忘了包括这个声明:
char line[] = " ";
为什么 8 可以,而 20 不行?
这表明line
没有定义足够的空间来包含 20 char
的可能性。 为了与您的代码片段保持一致, line
应定义为:
char line[20];
根据您对line
的实际定义,您可能会看到缓冲区溢出的结果。 它似乎工作,然后不工作的原因是undefined behavior ,这意味着任何行为都是可能的,并且在意外的时间。
此外,您应该考虑用while(!feof(fp))
while(fgets(line, 20, fp))
替换while(!feof(fp))
,它检查fgets
的返回作为测试,并在看到NULL
退出。 feof()
( 坏了)
while(fgets(line, 20, fp))//will exit loop upon a null return
{
//do something with line;
puts(line);
}
编辑以解决评论中的澄清问题:
如果您将line
声明为指针:
字符 * 行;
然后在其余代码中使用它之前,需要为指针指定一个地址,该地址具有足够包含 20 个char
相应内存。 此语句(以及确保内存已分配的测试)将执行以下两项操作:
line = calloc(20, 1);
if(line)
{
//use line as described above
编辑 2以解决 OP 中的新信息。
由于line
被定义为(稍后编辑为 OP)
char line[] = " ";
它只有 1 个字符的空间。 这将导致缓冲区溢出,并解释了观察到的不一致行为(并在帖子中写到)。
定义line
以支持帖子中显示的代码需要的建议方法是:
char line[20] = {0}; //space for 20 char, initialized to all zeros.
这与有关用fgets
替换feof
的其他建议一起将提高您看到的性能,并消除由于缓冲区溢出而导致的未定义行为
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.