我正在为文件编写一个RAII包装器*。我注意到,当文件*在析构函数关闭后被删除时,它会导致未定义的行为(seg )。其他地方的错误)。我假设fclose会将文件*设置为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;
};发布于 2011-09-01 22:00:28
当然,delete fp造成了一场崩溃。它不是用new分配的。只对您从new中得到的东西或文档告诉您使用它的其他东西调用new。fopen的文档从未告诉您使用delete。文件的所有清理都是由fclose执行的;在调用了文件相关资源之后,不需要做任何额外的工作来释放它。
设置fp = NULL是可以的。这种“智能文件指针”的未来使用者可以检查指针是否仍然有效,这可能是可取的。(但是,在reset方法中,它比析构函数更有用;在析构函数运行之后,不可能有任何指针类的使用者,因为对象已经不存在了。)但是fclose本身不能这样做,因为fclose不能通过引用来接收它的参数,而且即使它接收了参数,它也不能使文件指针的所有可能副本失效。回想一下,free和delete也没有将它们的参数设置为NULL。
发布于 2011-09-01 22:01:53
不,您不应该尝试delete一个文件*。它是一个C库数据结构,不表示从C++ new返回的指针。
发布于 2011-09-01 22:02:08
fp不是由C运行时分配的,您不必释放它。fclose不能将其设置为NULL,因为它不能将其设置为null (它是指向文件结构的指针,而不是指向文件*的指针)。
如何分配FP与您无关,它不是您与API的合同的一部分,所以不要担心它。
增编:
fopen正在返回指向文件结构的指针。内存的位置和获取方式并不重要。它很可能指向内存中的静态结构。但是,基本上,你不应该对那些记忆负责,所以你不应该把它弄乱。
现在,实际的fp指针,您可以分配:
FILE **fp = malloc(sizeof(FILE *));
*fp = fopen("file.txt", "r");
...
fclose(*fp);
free(fp);但是,很明显,大多数人不会这么做,他们只是使用一个本地堆栈变量来管理它。取决于用例。
https://stackoverflow.com/questions/7277030
复制相似问题