C 在循环中释放内存,而不考虑返回代码
我有以下C伪代码:C 在循环中释放内存,而不考虑返回代码,c,loops,error-handling,goto,C,Loops,Error Handling,Goto,我有以下C伪代码: int main() { int rc = 0; for (int i = 1; i < 10; i++) { char *data = malloc(i); // Each iteration has a different alloc size rc = do_something(data); if (rc != 0) goto cleanup; rc = do_something
int main()
{
int rc = 0;
for (int i = 1; i < 10; i++) {
char *data = malloc(i); // Each iteration has a different alloc size
rc = do_something(data);
if (rc != 0) goto cleanup;
rc = do_something_else();
if (rc != 0) goto cleanup;
cleanup:
free(data);
if (rc != 0) break;
}
return rc;
}
intmain()
{
int rc=0;
对于(int i=1;i<10;i++){
char*data=malloc(i);//每个迭代都有不同的alloc大小
rc=做某事(数据);
如果(rc!=0)转到清理;
rc=做点别的事();
如果(rc!=0)转到清理;
清理:
免费(数据);
如果(rc!=0)中断;
}
返回rc;
}
我想模拟Python的try…finally
模式,在调用的函数返回错误时中断循环,但仅在完成一些必要的清理工作之后
到目前为止,代码在我看来还行,但我对C还是新手。是否有一种不同的模式可以避免重复的
rc!=0
免费后测试?(我知道有些人认为<代码> Goto 无条件错误,但我认为它是对这种情况最干净的解决方案。) < P>从我的经验来看,很少有一个真正简单的解决方法来解决C.中的错误处理问题。
你可以这样做,但如果这真的更好,这是有争议的
int main()
{
int rc = 0;
for (int i = 1; i < 10; i++) {
char *data = malloc(i); // Each iteration has a different alloc size
rc = do_something(data);
if (rc != 0) goto cleanup;
rc = do_something_else();
if (rc != 0) goto cleanup;
free(data);
continue;
cleanup:
free(data);
break;
}
return rc;
}
intmain()
{
int rc=0;
对于(int i=1;i<10;i++){
char*data=malloc(i);//每个迭代都有不同的alloc大小
rc=做某事(数据);
如果(rc!=0)转到清理;
rc=做点别的事();
如果(rc!=0)转到清理;
免费(数据);
继续;
清理:
免费(数据);
打破
}
返回rc;
}
如果需要资源管理,并且需要执行一组检查,而每次故障都需要停止流并执行所需的清理,则可以使用这种模式(使用转到
)
在我看来,要使代码更干净,就要放置rc!=0
循环的内的条件:
int rc = 1;
for (int i = 0; i < 10 && rc != 0; i++)
{
...
请注意,释放一个NULL
指针是完全合法的。在您所展示的特定代码/案例中,您可以通过使用函数而不是malloc
来消除任何类型的每循环清理的需要。这将简单地用一个新的块(大小不同)替换上一个循环(如果有)上分配的内存。然后,您可以简单地将任何清理(即调用free
)延迟到循环之外
char *data = NULL;
for (int i = 1; i < 10; i++) {
data = malloc(i); // Each iteration has a different alloc size
rc = do_something(data);
if (rc != 0) break;
rc = do_something_else();
if (rc != 0) break;
free(data);
data = NULL;
}
if (data) {
free(data);
}
无论何时发生错误,您仍然可以使用break
语句退出循环;或者,如评论中所述,您可以添加一个rc!=0
测试循环的条件
下面是一些C代码,它将按照我所指出的那样工作(但是,当然,您需要两个名为functions的实际定义才能工作):
#包括
int do_something(字符*数据);
int do_something_other(void);
int main()
{
int rc=0;
char*data=NULL;
对于(大小i=1;i<10;i++){
char*temp=realloc(data,i);//如果“data”为NULL(第1个循环)->与malloc相同
如果(temp==NULL){//分配失败。。。
//错误消息
打破
}
data=temp;//成功分配,因此更新“data”指针
rc=做某事(数据);
如果(rc!=0)中断;
rc=做点别的事();
}
free(data);//我们现在只需要清理一次(允许使用NULL调用)。
返回rc;
}
请随时要求进一步澄清和/或解释。您可以在循环之外声明变量。然后只要在释放变量时将其设为null,并在循环结束后检查是否存在此问题
char *data = NULL;
for (int i = 1; i < 10; i++) {
data = malloc(i); // Each iteration has a different alloc size
rc = do_something(data);
if (rc != 0) break;
rc = do_something_else();
if (rc != 0) break;
free(data);
data = NULL;
}
if (data) {
free(data);
}
char*data=NULL;
对于(int i=1;i<10;i++){
data=malloc(i);//每个迭代都有不同的alloc大小
rc=做某事(数据);
如果(rc!=0)中断;
rc=做点别的事();
如果(rc!=0)中断;
免费(数据);
数据=空;
}
如果(数据){
免费(数据);
}
您可以添加rc!=0
进入for
循环:for(int i=0;i<10&&rc!=0;i++)
。。。只需初始化rc=1代码>而不是0。在这种情况下,您不需要使用中断
@AlexLop。美好的这比我的答案还要好。这非常吸引人,可能适用于我的真实代码,其中alloc和free调用在一个单独的函数中,但它提出了一个更广泛的问题:在被调用的函数中是否有人担心用realloc替换malloc,哪一个是泛型的,在广泛的上下文中被调用?@user3758232如果你总是有一个malloc的循环模式。。。免费
,然后将其替换为realloc
(在循环中)和循环后的单个免费
,不会改变整体行为模式(只要采取相关预防措施防止调用realloc
,如我在代码中所示)。@user3758232,如果传递指向使用realloc
的函数的指针,则必须传递指向指针的指针,才能将修改后的值返回给调用方。但当你使用malloc
时,情况可能也是如此。我已经接受了一个答案,但这实际上是最通用的答案,因为它适用于不特定于alloc
/realloc
的情况,或者我无法修改该代码的情况。