我有这个功能
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()
调用不够?
有人有想法吗?
答案 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块中。
另请注意,您未能检查其余的文件操作。 fseek
,ftell
和fread
都可能失败。您需要对所有这些进行类似的检查。我不建议使用错误处理来乱丢你的代码,而是可能忘记在几个地方执行它,我建议写一些包装器。
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)
,以便了解失败的原因。