【问题标题】:Can you delete a FILE object created from fopen?你能删除从 fopen 创建的 FILE 对象吗?
【发布时间】:2014-09-08 23:17:30
【问题描述】:

在调查崩溃时,我遇到了以下代码:

FILE * RejectFile = fopen("filename", "a+");
// other code happens
delete RejectFile;

我的理解是你只对new创建的对象调用delete。当然,有些旧代码确实很糟糕,所以这很可能是错误的,但我不确定。这是有效的代码吗?

【问题讨论】:

  • 应该是 FILE * 而不是 FILE 并且不,您不应该进行删除。我的理解是 fopen() 提供的 FILE 指针是运行时拥有的运行时事物。可能只是指向作为运行时环境一部分的静态分配内存区域的指针。
  • 啊,原来是FILE *,我刚才复制错了。

标签: c++ fopen


【解决方案1】:

不,这是无效的。只在通过new 获得的指针上使用delete。这里发生的是未定义的行为;它可能会工作,它可能会崩溃,它可能会输出垃圾,它可能会开始播放一些音乐......

你需要使用fclose()来销毁文件句柄。

【讨论】:

  • 措辞得当,因为它可能会根据平台和标准库意外正常工作。
  • 关闭并释放文件资源可能是一个比销毁更合适的术语。
  • @RichardChambers 我将“resource”更改为“handle”以明确句柄是被破坏的对象,而不是文件本身。
  • 我真的很想看它播放音乐。
  • @JesseJ ...你的意思是听到吗? ;)
【解决方案2】:

如果你真的需要使用删除,你可以使用一些包装这些结构。喜欢,

class MyFILE
{
public:
    MyFILE(/*file params*/);
    virtual ~MyFILE(){fclose(_fileptr);
private:
    FILE * _fileptr;
}

一个示例用法是,

MyFILE * f = new MyFILE(/*file params*/);
delete f;

就我个人而言,我更喜欢这种包装解决方案,因为它提供了一种全面的资源管理方式。例如,当我们处理一个代码段时,它的任何部分都可以随时抛出异常。如果我们已经分配了诸如打开文件之类的资源,那么当包装器将对象超出范围时,这种机制就可以“自动”删除对象。

【讨论】:

  • 当然,如果我们正在寻找一种 C++ 方式来做到这一点,我们将使用std::ofstream,或者至少我们可以提供struct file_deleter { operator()(FILE * f) { fclose(f); } },然后我们可以使用std::unique_ptr<FILE, file_deleter> f {fopen(...)};创建新类型。
  • @cdhowie 我同意。我只是想提一下 Resource Acquisition Is Initialization 的想法以及如何使用它。如果我们将“资源”视为“文件”,是的,我们有几种方法可以轻松或更短的方法来实现这一目标。另一方面,例如,如果我们需要考虑网络套接字描述符,这个概念仍然有效。我的意思是虽然我们有针对特定情况的更简单的版本,但它通常可以工作。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-05-26
  • 1970-01-01
  • 2019-02-22
  • 2013-07-22
  • 2017-02-01
  • 1970-01-01
相关资源
最近更新 更多