【发布时间】:2011-09-01 21:58:27
【问题描述】:
我正在为 FILE * 编写一个 RAII 包装器。我注意到当 FILE * 在析构函数中关闭后被删除时,它会导致未定义的行为(例如错误或其他地方的错误)。我假设 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 个字节。但看起来这不是必需的。
【问题讨论】:
-
您为什么要为
FILE*编写 RAII 包装器?如果您已经在使用 C++,为什么不直接使用fstream? -
升级旧软件是一个常见的原因。我已经做到了。与将其全部替换为流相比,文件* 周围的 RAII 更改要小得多。
-
@Adam - MD 是对的。用 fstream 替换现有文件 * 需要更多更改,特别是如果某些用于读取二进制文件的库需要传递 FILE * 时。