C++ 为什么fclose不将文件指针设置为NULL?
我正在为文件*编写RAII包装。我注意到,当文件*在析构函数中关闭后被删除时,会导致未定义的行为(seg.fault或其他地方的错误)。我假设fclose会将文件*设置为NULL,但它没有设置C++ 为什么fclose不将文件指针设置为NULL?,c++,pointers,fclose,C++,Pointers,Fclose,我正在为文件*编写RAII包装。我注意到,当文件*在析构函数中关闭后被删除时,会导致未定义的行为(seg.fault或其他地方的错误)。我假设fclose会将文件*设置为NULL,但它没有设置 class smartFP { smartFP (const std::string& name) : fp (fopen(name.c_str(), "r") { } ~smartFP() { if (fp) { fclose(fp);
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;
};
class-smartFP{
smartFP(常量标准::字符串和名称)
:fp(fopen(name.c_str(),“r”)
{ }
~smartFP()
{
if(fp){
fclose(fp);
//删除(fp)当然delete fp
会导致崩溃。它没有被分配new
。只需调用delete
就可以使用new
或文档告诉您要使用它的其他内容。fopen
的文档从不告诉您使用delete
。所有文件的清理工作都会进行由fclose
执行;在调用文件相关资源后,无需执行任何其他操作即可释放该资源
设置
fp=NULL
很好。这可能是可取的,以便将来使用此“智能文件指针”的用户可以检查指针是否仍然有效。(不过,reset
方法比析构函数更有用;析构函数运行后,指针类不会有任何未来的使用者,因为对象不再存在。)但是fclose
本身无法做到这一点,因为fclose
不会通过引用接收其参数,即使它接收了,也无法使文件指针的所有可能副本无效。请记住free
和delete
也不会将其参数设置为NULL
。不,您不应该E试图编写<代码>删除< /C>文件>它是C库数据结构,并不代表从C++代码>新的返回的指针。FP没有被C运行时分配,你不必释放它。FSET不将它设置为NULL,因为它不能将它设置为NULL(它是指向文件结构的指针,而不是文件*)。 FP的分配方式与您无关,它不是API合同的一部分,所以不用担心
增编: fopen返回指向文件结构的指针。它从何处以及如何获取内存并不重要。它很可能指向内存中的静态结构。但是,基本上,您不应对该内存负责,因此不应该弄乱它 现在,对于实际的fp指针,您可以分配:FILE **fp = malloc(sizeof(FILE *));
*fp = fopen("file.txt", "r");
...
fclose(*fp);
free(fp);
但是,很明显,大多数人不会这样做,他们只是使用一个本地堆栈变量来管理它。这取决于使用情况。
fopen
和fclose
使用FILE*
元素进行必要的动态内存管理,因此您不必对它们调用delete
。如果您使用ant,表示未分配文件。1)fclose无法将文件*设置为NULL,因为它的参数是文件*,因此它按值接收文件*。由于它是副本,因此它无法更改指针,除非参数更改为文件*&。2)在C++中,你几乎不调用<代码>删除>代码>除非你调用了代码>新的<代码>。如果你正在做RAII,你只应该把代码<新>代码>分配给智能指针,并且永远不要调用<代码>删除>代码>。为什么你要为
get
方法很好,但你在析构函数中的操作对你没有任何帮助。如果有人调用get
并存储结果的副本,他们就有结果的副本。你可以更改UR <代码> FP>代码>变量,但不影响拷贝中的值。请考虑此代码:<代码>文件*fp= fOpen.(…);文件*b= FP;fCAMP(FP);fp=NULL;将fp
设置为NULL
不会更改b
。无论fp
是类的成员还是b
的赋值是在调用某个get
方法之后进行的。@srikrish仅仅因为您将类中的指针成员设置为NULL并不意味着他们保存的副本将设置为空。另外,Rob,fclose
是一个C函数,因此它不可能通过引用接收文件*
(当然可能需要文件**
。@Rob-感谢您的澄清。因此,当我执行fp=fopen(…),是在调用函数的堆或堆栈上分配的fp。类似地,当您坐在“所有由fclose完成的文件的清理”位置时,这是否意味着为私有成员fp(在堆栈或堆中)分配了空间是取消分配还是以后再发生。@Rob-是否也会在堆栈或堆中为文件*b(fp的副本)分配空间?是否有允许此复制的文件*的复制分配运算符。正如我所解释的,删除fp的原因是释放fopen分配给私有成员fp的任何空间。因为,我认为fclose只会释放在内存中分配给文件的空间,我想删除fp并释放空间。现在还不清楚,为什么不需要。是因为fclose做这个工作。