return导致内存泄露。C函数中不要有多次return,以及其解决方法。goto的用法。

函数中随处return,是造成我们资源泄露和程序死锁的主要根源。很多同志写过类似的代码,函数中创建了和引用了多个资源,中间使用的过程中出错了,程序return,经典的代码是这样的:

void fun()  
{
    Lock(mutex);
    mem = malloc(size);
    if (null == mem)
    {          
        return; //死锁     
    }     
    fh = fopen(“test.txt”);     
    if (fh)      
    {          
        return; //死锁+内存泄露     
    }     
    if (fwrite(“abc”, fh) < 0)      
    {          
        return; //死锁+内存泄露+句柄泄露     
    }     
    fclose(fh);      
    free(mem);      
    Unlock(mtex);
}

上述代码中的资源泄露是显而易见的,编程新手却很容易写出这样的代码,但问题却不容易发现,因为异常流程通常不会发生,而一旦发生了,就是一场噩梦:不好跟踪也不好重现。对吃过这种亏编程老手而言,处理起来会格外小心,而是有了如下版本的代码(我们的工程中类似的代码随处可见):

void fun()  
{
    Lock(mutex);
    mem = malloc(size);     
    if (null == mem)      
    {          
        Unlock(mutex); //锁解除了,很好         
        return;      
    }   
    fh = fopen(“test.txt”);     
    if (fh)      
    {          
        Free(mem);          
        Unlock(mutext); //错误处理加了一行         
        return;      
    }    
    if (fread(mem, size, fh) < 0)      
    {          
        Free(mem);          
        Flcose(fh);          
        Unlock(mutext); //错误处理又加了一行…         
        return;      
    }   
    fclose(fh);      
    free(mem);      
    Unlock(mtex);
}

 

这个版本的代码没什么逻辑问题,在每个异常环节,把该处理的都处理完了。看起来非常完美,却依然存有大坑。首先,我们的异常处理流程越来越长,重复的代码像火车车厢一样越串越长,代码维护非常不方便,某天其中一个异常处理流程要修改了,我们需要修同步多处,万一漏了某处(事实上不是万一,而是经常),问题没有修改彻底;更为严重的是,冗于的异常处理会让大家感到疲劳,某一天函数中又要加入新的资源引用或异常处理逻辑时,在先驱的引导下,我们的人依然还是会犯同样的错误:要么什么都不管提前返回,或者处理不充分就走了,结果还是同样的资源泄露。

如何解决,Linux内核代码给了我们很好的解决方案,合理地使用goto语句,将异常处理定向到统一的地方,既解决了资源泄露隐患,也保持了正常流程代码的简洁性,这是改进后的版本:

void fun()  
{      
    Lock(mutex);   
    mem = malloc(size);     
    if (null == mem)      
    {          
        goto ERR_EXIT1;      
    }     
    fh = fopen(“test.txt”);     
    if (fh)      
    {          
        goto ERR_EXIT2;      
    }     
    if (fread(mem, size, fh) < 0)      
    {         
        goto ERR_EXIT3;      
    }   
    ERR_EXIT3:      
    fclose(fh);  
    ERR_EXIT2:      
    free(mem);  
    ERR_EXIT1:      
    Unlock(mtex);  
}

总结:以后新写C代码的异常处理,统一采用上面的模版。C++/java有更好的异常处理机制,上述方案只供参考,但解决思路应该是一致的,随处return与冗余异常处理应该被严厉禁止。

 

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
ava实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),可运行高分资源 Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值