在 C 中的每次错误检查后如何避免长链空闲(或删除)? [英] How to avoid long chain of free's (or deletes) after every error check in C?
问题描述
假设我非常谨慎地编写代码并始终检查我调用的所有函数的返回类型.
Suppose I write my code very defensively and always check the return types from all the functions that I call.
所以我喜欢:
char* function() {
char* mem = get_memory(100); // first allocation
if (!mem) return NULL;
struct binder* b = get_binder('regular binder'); // second allocation
if (!b) {
free(mem);
return NULL;
}
struct file* f = mk_file(); // third allocation
if (!f) {
free(mem);
free_binder(b);
return NULL;
}
// ...
}
注意 free()
事情失控的速度有多快.如果某些功能失败,我必须先释放每个分配.代码很快变得丑陋,我所做的就是复制粘贴所有内容.我成为了一个复制/粘贴程序员,更糟糕的是,如果有人在两者之间添加了一条语句,他必须修改下面的所有代码以调用 free()
进行添加.
Notice how quickly free()
things get out of control. If some of the function fails, I have to free every single allocation before. The code quickly becomes ugly and all I do is copy paste everything over. I become a copy/paste programmer, even worse, if someone adds a statement somewhere in between, he has to modify all the code below to call the free()
for his addition.
有经验的 C 程序员如何解决这个问题?我什么都想不通.
How do experienced C programmers go about this problem? I can't figure anything out.
谢谢,博达·西多.
推荐答案
你可以定义一个新的标签来释放资源,然后你可以在代码失败时转到它.
You could define a new label that would free the resources and then you could GOTO it whenever your code fails.
char* function()
{
char* retval = NULL;
char* mem = get_memory(100); // first allocation
if (!mem)
goto out_error;
struct binder* b = get_binder('regular binder'); // second allocation
if (!b)
goto out_error_mem;
struct file* f = mk_file(); // third allocation
if (!f)
goto out_error_b;
/* ... Normal code path ... */
retval = good_value;
out_error_b:
free_binder(b);
out_error_mem:
free(mem);
out_error:
return retval;
}
这里已经讨论了使用 GOTO 的错误管理:在 C 中有效使用 goto 进行错误管理吗?
Error management with GOTO was already discussed here: Valid use of goto for error management in C?
这篇关于在 C 中的每次错误检查后如何避免长链空闲(或删除)?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!