【问题标题】:open a file in a non existing directory c versus c++在不存在的目录中打开文件 c 与 c++
【发布时间】:2020-01-16 12:37:22
【问题描述】:

我尝试在 C++ 中不存在的目录中打开一个文件,但由于某种原因,我的应用程序没有崩溃。我觉得这有点“奇怪”,因为我习惯了 C,等效程序确实会崩溃。这是我的 C++ 版本,后面是等效的 C 版本:

$ cat main.cpp
#include <fstream>
int main(int argc, char **argv)
{
    std::ofstream f("/home/oren/NON_EXISTING_DIR/file.txt");
    f << "lorem ipsum\n";
    f.close();
    printf("all good\n");
}
$ g++ main.cpp -o main
$ ./main
all good

当我尝试用 C 做同样的事情时,我得到一个段错误:

$ cat main.c
#include <stdio.h>
int main(int argc, char **argv)
{
    FILE *fl = fopen("/home/oren/NON_EXISTING_DIR/file.txt","w+t");
    fprintf(fl,"lorem ipsum\n");
    fclose(fl);
    printf("all good\n");
}
$ gcc main.c -o main
$ ./main
Segmentation fault (core dumped)

这是为什么呢?

【问题讨论】:

  • 您的程序崩溃不是因为它无法打开文件,而是因为它取消了对空指针的引用。
  • “不崩溃”并不意味着“它有效”。
  • 任何程序在尝试打开不存在的文件时都不应崩溃。试图打开一个不存在的文件是一种普通的失败模式,任何文件打开程序都应该优雅地处理它。 C 程序必须在调用 fopen 后检查返回的指针,如果指针为 NULL,则不尝试继续。 C++ 程序应该做类似的事情。

标签: c++ c file ofstream


【解决方案1】:

我习惯了 C”,但后来是“[...] in C++ " - 好吧,C++ 不是 C,但这在这里无关紧要。首先,看看this - 在设置失败位后,写入未打开的流(这里就是这种情况)被忽略。

但是,在您的 C 示例中,问题是如果 fopen fais,它会返回一个 NULL 指针。然后将其传递给fprintf。这就是 Undefined Behaviour1 发生的地方。在C++ 示例中没有这样的事情。


1请注意C 示例不保证 SEGFAULT。未定义的行为是未定义的。

【讨论】:

    【解决方案2】:

    使用函数的文档是关键。在这两种情况下,程序都无法打开文件。但是由于某些原因,C++ 库的概念不允许它在构造函数中崩溃。 ofstream 实际上使用相同的fopen 或类似的功能。 让我们看看手册是怎么说的:

    fopen()、fdopen() 和 freopen() 成功完成后返回一个 文件指针。否则,返回 NULL 并将 errno 设置为 指出错误。

    所以你必须检查返回值是否为 NULL,否则你有一个未定义的行为。 ofstream 会为你做这件事,在对象初始化期间不会发生未定义的行为。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-12-01
      • 2017-07-25
      • 1970-01-01
      • 1970-01-01
      • 2019-08-02
      相关资源
      最近更新 更多