【问题标题】:Why does fopen works without saving the returned pointer?为什么 fopen 在不保存返回的指针的情况下工作?
【发布时间】:2016-02-17 10:54:38
【问题描述】:

我写了一个小程序来解密一个 OTP 加密的文件。这工作得很好。

但我意识到我在“Solution.jpg”上调用 fopen 时忘记保存返回的文件指针。如您所见,我正在写入文件指针 f。我想知道为什么这段代码有效。

#include <stdio.h>

#define FILE_SIZE 4202

int main () {
    unsigned char key[FILE_SIZE], otpCipher[FILE_SIZE];

    FILE *f = fopen("otpkey.bin", "r");
    fread(key, sizeof(char), FILE_SIZE, f);
    fclose(f);

    f = fopen("otpcipher.bin", "r");
    fread(otpCipher, sizeof(char), FILE_SIZE, f);
    fclose(f);

    fopen("Solution.jpg", "w");

    for (int j = 0; j < FILE_SIZE; ++j) {
        otpCipher[j] = otpCipher[j] ^ key[j];
        fputc(otpCipher[j], f);
    }

    fclose(f);

    return 0;
}

【问题讨论】:

  • f 关闭后无效。因此,之后在任何其他函数中使用它都是未定义的行为。 UB 意味着它可以工作,但也可能崩溃,或写入其他文件,或静默继续,或任何其他未定义的操作。
  • fputc(otpCipher[j], f); 正在写信给Solution.jpg 吗?我不这么认为......
  • @LPs 我认为在 OP 的情况下确实如此。因为fopen("Solution.jpg", "w"); 恰好为FILE 重用了相同的内存,因为指针f 已经引用了。所以f 中用于fputc 的指针是偶然有效的。
  • 你说它“工作”只是因为它碰巧做了你想做的事。如果你想让它做其他事情,它就不会工作。它正在做一些你没有告诉它去做的事情,所以我不会说它正在工作。

标签: c pointers fopen


【解决方案1】:

我刚刚使用 gdb 找到了答案。

因此,由于我在打开新文件之前使用了fclose(),因此释放了指向之前使用的文件的指针。这个指针可以再次使用,每次我运行这个程序时fopen()都会返回这个指针。

之所以成功,是因为在我调用fopen() 时没有打开其他文件。

这是未定义的行为,可能会导致其他问题。在任何情况下都应该避免(我是错误地这样做的)。我只是想了解为什么这会起作用并修复了我的代码。

【讨论】:

  • 您正确地诊断了实际行为,但请注意,C 标准绝不允许这样做。在调用fclose(f) 之后使用f 是未定义的行为。 fopen() 返回相同的指针是一个小奇迹,当然不要依赖它。另请注意,您还应该检查fopenfread 的返回值。
  • 谢谢,我知道这是一件坏事。因此,为了清楚起见,我将其添加到我的答案中。
  • +1 既可以自己使用 gdb 探索问题,也可以意识到/接受“它恰好可以工作”并不是一个好的状态。
猜你喜欢
  • 2011-08-24
  • 1970-01-01
  • 2023-03-17
  • 2015-01-04
  • 1970-01-01
  • 1970-01-01
  • 2019-02-24
  • 2015-04-01
  • 1970-01-01
相关资源
最近更新 更多