经常使用fopen时出错

时间:2017-01-29 21:54:29

标签: c function file fopen dynamic-memory-allocation

我有这个功能

 char* Readfiletobuffer(char* file, FILE* fp){
     char * buffer;
     int file_size;

     fp = fopen(file, "r");

     if (fp != NULL) {
         fseek(fp, 0, SEEK_END);
         file_size = ftell(fp);
         buffer = (char*) malloc((file_size + 1) * sizeof(char));
         fseek(fp, 0, SEEK_SET);
         fread(buffer, file_size, 1, fp);
         buffer[file_size] = '\0';
         return buffer;
     } else {
         printf("error loading file");
     }

     fclose(fp);
 }

我在程序中调用1050次,在1019 th 时间fopen()返回NULL指针。

它不依赖于文件,它始终是1019 th 时间,所以我认为这是释放内存但为什么fclose()调用不够?

有人有想法吗?

1 个答案:

答案 0 :(得分:2)

您的程序可以通过errno告诉您全局变量,其中许多函数在失败时将错误代码分配给它们。结合strerror提供人类可读的错误消息,您可以将错误处理更改为类似的内容。

#include <errno.h>
#include <string.h>

...

fp = fopen(file, "r");
if (fp == NULL) {
    fprintf(stderr, "Could not open '%s': %s", file, strerror(errno));
    exit(1);
}

fseek(fp, 0, SEEK_END);
file_size = ftell(fp);
...

注意使用early exit来消除将整个函数嵌套在if / else块中。

另请注意,您未能检查其余的文件操作。 fseekftellfread都可能失败。您需要对所有这些进行类似的检查。我不建议使用错误处理来乱丢你的代码,而是可能忘记在几个地方执行它,我建议写一些包装器。

FILE *open_file(const char *filename, const char *mode) {
    FILE *fp = fopen(filename, mode);
    if( fp == NULL ) {
        fprintf(
            stderr, "Could not open '%s' for '%s': %s\n",
            filename, mode, strerror(errno)
        );
        exit(1);
    }

    return fp;
}

请注意,这不是最好的错误处理,它只是在出错时退出。在你学习C的这个阶段,最好只是挽救一个错误。如果你做了类似return NULL的赔率,你就不会有错误处理来处理一个空指针,它只会反弹导致神秘的问题并在代码后面崩溃。现在,最好尽可能地停止并着火。

Spoiler alert:您的流程用尽了文件句柄,因为您没有关闭文件。正如您fclose @BLUEPIXY correctly points out in the comments正常返回后,-Wall只会在文件无法打开时发生。

由于您传入了文件指针,可能以后打算使用它?在这种情况下,您无法保留那么多打开的文件,并且您必须重新设计代码。如果没有,由于函数打开它,没有理由将它传入。

如果您使用test.c:23:1: warning: control may reach end of non-void function [-Wreturn-type] } 启用了警告,则应该收到类似警告。

strerror(errno)

如果文件无法打开,则不会返回任何内容,并且不正常。

不要忽视你的警告,修复所有警告。调查这个警告会指出你的问题。

  • 检查所有文件操作以确保它们成功。
  • 在错误消息中包含if (fileIn),以便了解失败的原因。
  • 调查并修正所有警告。