在不存在的目录中打开文件,C 与 C++



我试图在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 ipsumn";
f.close();
printf("all goodn");
}
$ 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 ipsumn");
fclose(fl);
printf("all goodn");
}
$ gcc main.c -o main
$ ./main
Segmentation fault (core dumped)

为什么?

">

我习惯了C",但随后">[...]在C++" - 好吧,C++不是C,但这在这里无关紧要。首先,看看这个 - 在设置故障位后,对未打开的流的写入(这里就是这种情况(将被忽略。

但是,在您的C示例中,问题是如果fopenfais,它会返回一个NULL指针。然后你把它传递给fprintf.这就是未定义行为1发生的地方。在C++的例子中没有这样的事情。


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

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

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

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

最新更新