如何确保 malloc/free fopen/fclose 匹配?
我认为下面的代码是正常的(和malloc/free类似):
int foo(){
FILE *fp = fopen("test.in", "r");
int i;
for(i = 0; i < NUM; i ++){
if(Match(fp, i)){
fclose(fp);
return i;
}
}
fclose(fp);
return 0;
}
正如我们所看到的,fclose(fp)
在代码中出现了两次。如果函数foo中还有其他return语句,则会出现更多。不过很麻烦的是要多次写fclose(fp)
。一种解决方案就是一个函数的一次返回。然而,多重回报有时是有用的。还有其他解决办法吗?
PS:据我所知,lisp中有一个宏(with-open-file)。
(with-open-file (stream-var open-argument*)
body-form*)
它可以为我们打开和关闭文件。
I think the following code is normal (and malloc/free is similar):
int foo(){
FILE *fp = fopen("test.in", "r");
int i;
for(i = 0; i < NUM; i ++){
if(Match(fp, i)){
fclose(fp);
return i;
}
}
fclose(fp);
return 0;
}
As we can see fclose(fp)
appears twice in the code. It will appear more if there are other return statements in the function foo. However, it is troublesome that I have to write fclose(fp)
many times. One solution is just one return for one function. However, multiple returns is sometimes useful. Is there any other solution?
PS: As I know, there is a macro(with-open-file) in lisp.
(with-open-file (stream-var open-argument*)
body-form*)
It could open and close file for us.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
![扫码二维码加入Web技术交流群](/public/img/jiaqun_03.jpg)
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
使用
break
通常有帮助:The use of
break
often helps:在Linux内核的源代码中,有许多函数必须在返回时处理锁和其他资源。他们通常在函数末尾添加一个清理标签,并在发生提前返回时
转到
那里。我个人推荐这种用法以避免重复代码,也许这是goto
唯一合理的用法。In the source code of linux kernel, there are many functions that have to take care of locks and other resource on return. And they conventionally add a cleanup label at the end of the function, and
goto
there whenever early return occurs. I personally recommend this usage to avoid duplicate code, and maybe this is the only sane usage ofgoto
.额外的间接层可以确保您不会错过函数的退出:
An extra layer of indirection can ensure you don't miss an exit from the function:
我将通过 goto 扩展异常处理(在 @Charles Peng 的回答中提到):
你可以这样做:
这样做的优点是它非常易于维护。使用此惯用语时,资源获取和释放具有某种对称的外观。此外,资源释放不在主要逻辑之外,避免了最令人烦恼的过度混乱。检查函数的错误处理是否正确是非常简单的(只需检查它是否跳转到适当的点,以及前一个标签是否释放了任何获取的资源)...
I'll expand on exception handling via goto (mentioned in @Charles Peng's answer):
You do it something like:
The advantage of this is that it's very maintainable. Resource acquisition and release has a somewhat symmetrical look when using this idiom. Also, resource release is out of the main logic, avoiding excessive clutter where it annoys the most. It's quite trivial to check that error handling of functions is right (just check that it jumps to the appropiate point, and that the previous label releases any acquired resource)...
不在函数末尾的 return 语句相当于 goto 语句。尽管看起来有些函数使用多个 return 语句会更简单,但根据我在维护各种代码库时的经验,每个函数只有 1 个退出点的代码库更容易维护。
A return statement NOT at the end of a function is the equivalent of a goto statement. Even though it may appear as though some functions are simpler with multiple return statements it has been my experience while maintaining various code bases that the ones with only 1 exit point from every function are easier to maintain.