繁体   English   中英

使用 C 中的 fgets() 函数检测到堆栈粉碎

[英]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.

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