【发布时间】:2015-10-26 21:00:45
【问题描述】:
最近我在工作中遇到了一个问题,你有两个功能;一个人打开一个文件描述符(它是函数中的一个局部变量),并将它传递给另一个用于读取或写入的函数。现在,当其中一个操作读/写失败时,正在执行读/写的函数关闭此文件描述符,并返回。 问题是,谁的责任是关闭文件描述符,或者说做清理:
创建 fd 的函数
读/写时遇到错误的函数
这类情况有设计规则吗?让我们说创建和清理。
顺便说一句,问题是两个函数都试图关闭 fd,导致第二次调用 close 时崩溃。
【问题讨论】:
-
只需将其写入在任何给定时间拥有文件句柄所有权的那些函数的合同中。 PS:你用的是C还是C++?
-
如果你必须将
fd从一个函数传递到另一个函数并且任何一个都可以关闭它,只需将其设置为NULL。并且不要忘记在使用fclose之前先进行测试。但最简单的方法可能是避免该问题 - 如果发生错误,为什么要在函数内关闭文件?即使您喜欢这样,如果它确实出错了,为什么不将它传达给调用者呢? -
@Jongware:文件描述符是小(ish)整数;设置为 NULL 是不合适的,但 -1 可能是明智的。 OTOH,文件描述符很少作为指向
int的指针传递,因此更改很少会反映在调用代码中。 -
一般情况下,打开文件的函数应该关闭它;遇到错误的函数应该报告错误,但不关闭文件。但是,只要合同被记录和执行,您就可以按照自己喜欢的方式工作——调用代码需要知道被调用代码何时关闭文件以避免双重关闭。您确定您使用的是文件描述符而不是
FILE *(文件流)吗?两次关闭文件描述符不太可能导致崩溃(错误,是的,但不是崩溃)。 OTOH,在已关闭的文件流上调用fclose()可能会导致问题。 -
@Jongware:将
close()与错误(已关闭或永远无效)的文件描述符一起使用会生成-1 作为返回值,并且通常将errno设置为EBADF。没有崩溃的危险,因为不涉及指针。即使使用文件流,您也很少将FILE **传递给函数,因此被调用的函数仍然无法影响调用函数中的FILE *值。正如我在另一条评论中概述的那样,如果被调用的函数关闭文件,代码必须小心——如果不关闭文件通常是最好的,但只要每个人都知道发生了什么,这不是绝对必要的。