当 c 中的最后一行 fread 时,文件指针更改为 NULL

file pointer is changing to NULL when fread last line in c

提问人:NoamiA 提问时间:1/9/2023 最后编辑:ChrisNoamiA 更新时间:1/9/2023 访问量:96

问:

我有一个带有 5 个长 int 的二进制文件,一切都按预期工作,但是当我读取文件中的最后一项时,文件指针从 func2 返回 NULL,int 的 func2 文件指针的末尾仍然不为 null,但是当我回到 func1 时,我看到它变成了 naull,你能帮我理解为什么吗? 这是 2 个功能:

long int * func1(char * filename, int numOflogInts)
{
    long int numbers[5];
    FILE* fp = fopen(filename,"rb");
    for (int i = 0; i < numOflogInts; i++) {
        numbers[i] = func2(fp, i);
    }
    return numbers;
    fclose(fp);
}

long int func2(FILE * fp, int place)
{
    long int num;
    fseek(fp, sizeof(long int) * place, SEEK_SET);//skip to the place
    fread(&num, sizeof(long int), 1, fp);
    return num;
}
C 指针 null 二进制文件

评论

5赞 yano 1/9/2023
您将返回局部变量的地址,当函数结束时,该变量超出范围。此外,永远不会达到,一旦你就是这样,之后函数中不会执行任何内容。numbersfclose(fp)return
2赞 yano 1/9/2023
据推测,您正在返回时读取该值,这会调用未定义的行为,这意味着任何事情都可能发生。一个最小的可重现的例子将是最有帮助的。在尝试读取文件之前,还应该检查文件是否成功打开。
2赞 yano 1/9/2023
我在代码中没有看到直接原因,为什么会突然变成 NULL(除非从一开始就如此)。错误可能出在未显示的代码中,可能是其他一些 UB。..当然,除非我错过了它。fp
4赞 Avi Berger 1/9/2023
到底是什么?如果它的值> 5,则存在缓冲区溢出,这意味着内存损坏和未定义的行为。在这种情况下,事情错误地改变是公平的。@yano的观点可能是不同的问题,但它们也很重要。numOflogInts
1赞 Gerhardh 1/9/2023
如果是 6,则赋值将覆盖数组之后内存中的下一个内容,并且您很有可能命中该值。numOflogIntsnumbers[i] = func2(...numbersfp

答:

1赞 Chris 1/9/2023 #1

几个错误:

  • 您将返回需要在堆栈上分配的数组的地址。在此之后使用它会导致未定义的行为。
  • 此外,您返回了文件,然后关闭了文件指针。但是由于返回,这个电话是无法接通的。func1fclose
  • 你有一个常量,而不是用来确定数组的大小。你的循环表明这不是正确的做法。5numOflogInts

要解决第一个问题,请动态分配阵列。要修复第二个问题,请在返回之前关闭文件。

long int * func1(char * filename, int numOflogInts)
{
    long int *numbers = malloc(sizeof(long int) * numOflogInts);
    FILE* fp = fopen(filename,"rb");
    for (int i = 0; i < numOflogInts; i++) {
        numbers[i] = func2(fp, i);
    }
    fclose(fp);
    return numbers;
}

当然,您还需要检查内存分配和打开文件时是否存在错误。