fclose()导致分段错误

时间:2014-03-19 12:52:11

标签: c file-io segmentation-fault fopen fclose

我一直在C中尝试简单的文件处理,我想确保使用此文件可以访问该文件

#include<stdio.h>

main()
{
    CheckFile();
}

int CheckFile()
{
    int checkfile=0;

    FILE *fp1;
    fp1 = fopen("users.sav","r");

    if(fp1==NULL)
    {
        fopen("users.sav","w");
        fclose(fp1);
    }   
    if(checkfile!=0)printf("\nERROR ACCESSING FILE!\nNow exiting program with exit code: %d\n",checkfile);exit(1);
    return 0;
}

然后显示

Segmentation fault (core dumped)

但如果文件已预先存在(例如我手动创建或第二次运行程序时),则不会发生段错误。

请帮忙。我需要这个用于一周内的最终项目,但我还没有掌握文件和指针。

我正在使用&#34; gcc(Ubuntu / Linaro 4.8.1-10ubuntu9)4.8.1&#34;

P.S

我知道存在明显相似的问题,但请不要这样做。了解我已开始编写几个月的代码,因此无法理解这些高级代码和内容。

p.p.s

我在另一个问题中看到了这个

  

原始代码中不保证fopen实际上正在工作,在这种情况下它将返回NULL并且fclose将不会被定义为行为。

那么我该如何检查它是否有效?

5 个答案:

答案 0 :(得分:6)

当fp1为NULL时调用fclose(fp1)时,这是正常的。

顺便说一句

fopen("users.sav","w");

没用,因为您没有将返回值分配给文件指针。这意味着users.sav文件将被打开以进行写入,但您将永远无法在其中写入任何内容。

答案 1 :(得分:2)

fopen返回FILE指针。它将返回NULL并设置全局errno以指示错误。如果您想查看errno,则必须在检查fopen是否返回NULL后检查。

if (fp1 == NULL)
{
    printf("fopen failed, errno = %d\n", errno);
}

否则,您可能会从其他内容获得errno,而不一定是fopen来电。还包括errno.h。您也无需再次致电fopen("users.sav","w");。您不是重新分配指针也不是再次检查它。

我认为没有理由在此处致电fclose,因为如果fopen返回NULL,则无法关闭任何内容。这可能是你的seg错误的原因。您正在尝试关闭空指针。 More information on fopen failures

您的代码的另一个评论。如果您要从int返回CheckFile,则失败时可能不会0。我会返回-1来表示错误。更好的是,您可以返回全局errno。另外,main应该是int main(),最后你应该return 0;。我并不特别关心CheckFile的命名方案。在C中,check_filecheckFile的camelCase会更好。

CheckFile中,您的一行if语句可以格式化,并且如果您在多行格式化它,则可以更正常地工作。它不符合你的想象:

if(checkfile!=0)
{
   printf("\nERROR ACCESSING FILE!\nNow exiting program with exit code: %d\n", checkfile);
   exit(1);
}

此外,checkfile永远不会在您的代码中的任何位置设置..除了零。因此,if语句中的代码将不会执行,句点。

答案 2 :(得分:2)

我不确定你要做什么,但问题就在这里:

if(fp1==NULL)
   fclose(fp1);

断言fp1为NULL后,您尝试在空指针上调用close,这将导致分段错误。

如果您只想验证该文件是否存在,请尝试使用What's the best way to check if a file exists in C? (cross platform)

之类的内容

答案 3 :(得分:0)

fclose的手册页说 -

  

如果stream参数是a,则fclose()的行为是未定义的   非法指针,或者是已经传递给前一个的描述符   调用fclose()。

错误位于代码中的if块中。

if(fp1==NULL)
{
    fopen("users.sav","w");
    fclose(fp1);  // passing NULL to fclose invokes undefined behaviour
}   

答案 4 :(得分:0)

另一个不相关的问题:

这一行可能不是你想要的:

if(checkfile!=0)printf("\nERROR ACCESSING FILE!\nNow exiting program with exit code: %d\n",checkfile);exit(1);

如果我们正确地编写格式,则错误变得明显:

if (checkfile != 0)
  printf("\nERROR ACCESSING FILE!\nNow exiting program with exit code: %d\n",checkfile);

exit(1);
return 0 ;

实际上即使exit(1)为零,我们也会转到checkfile

你可能想要这个:

if (checkfile != 0)
{
  printf("\nERROR ACCESSING FILE!\nNow exiting program with exit code: %d\n",checkfile);
  exit(1); 
}

return 0 ;

结论:正确格式化代码,许多错误突然变得明显。