我正在为 FILE * 写一个 RAII 包装器。我注意到当 FILE * 在析构函数中关闭后被删除时,它会导致未定义的行为(seg.fault 或其他地方的错误)。我假设 fclose 会将 FILE * 设置为 NULL,但事实并非如此。
class smartFP {
smartFP (const std::string& name)
: fp (fopen(name.c_str(), "r")
{ }
~smartFP()
{
if (fp) {
fclose(fp);
// delete(fp); <- This is causing crash
fp = NULL; <- Is this OK?
}
}
private:
FILE *fp;
};
- 为什么 fclose 不将 FILE * 设置为 NULL?
- 第二个问题是fopen是在堆还是栈中为fp分配内存?我认为它在堆上执行,因此想在 fclose 之后执行删除操作,以便 fp 的堆上的 4 或 8 个字节被取消分配。但是看起来不需要这个。
最佳答案
当然 delete fp
会导致崩溃。它不是用 new
分配的。仅对使用 new
获得的内容或文档告诉您使用它的其他内容调用 delete
。 fopen
的文档从未告诉您使用 delete
。文件的所有清理都由 fclose
执行;在调用文件相关资源后,您无需执行任何其他操作即可释放它。
设置 fp = NULL
就可以了。这可能是可取的,这样这个“智能文件指针”的 future 消费者可以检查指针是否仍然有效。 (不过,它在 reset
方法中比在析构函数中更有用;在析构函数运行后,指针类不会有任何 future 的消费者,因为该对象不再存在。)但是fclose
不能自己做,因为 fclose
没有通过引用接收它的参数,即使它接收了,它也无法使 all 无效 文件指针的可能拷贝。回想一下,free
和 delete
也没有将它们的参数设置为 NULL
。
关于c++ - 为什么 fclose 不将文件指针设置为 NULL?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7277030/