函数中随处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与冗余异常处理应该被严厉禁止。

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

  1. ajax回调函数中不能触发input[type='file']事件的解决方法

    今天在做文件上传遇到一个问题,在ajax回调成功后触发input[type='file']元素的事件时始终不能弹出文件选择对话框 ,于是开始各种问题的排除,最终我发现在ajax 异步提交不行,要同步提 ...

  2. VC 2010的MFC函数,CMFCVisualManager::GetInstance()可能导致内存泄露

    今天在网上看到一篇文章,关于CMFCVisualManager的内存泄露问题( 链接是 http://zhanyonhu.blog.163.com/blog/static/16186044201132 ...

  3. pthread_create会导致内存泄露

    这几天一直在调试一个系统,系统的功能就是定时发送数据.接收数据然后解析收到的数据,转换成一定的格式存入数据库中.我为了并发操作,所以每接收到一个数据包,就调用pthread_create函数创建一个默 ...

  4. android如何避免内存泄露,Android开发中应该避免的内存泄露

    一.背景和目的: 目前许多开发人员在Android开发过程中,较少关注实现细节和内存使用,容易会造成内存泄露,导致程序OOM. 本文会通过代码向大家介绍在Android开发过程中常见的内存泄露. 二. ...

  5. 使用ThreadLocal不当可能会导致内存泄露

    使用ThreadLocal不当可能会导致内存泄露 基础篇已经讲解了ThreadLocal的原理,本节着重来讲解下使用ThreadLocal会导致内存泄露的原因,并讲解使用ThreadLocal导致内存 ...

  6. String 使用不当可能导致内存泄露

    转载自   String 使用不当可能导致内存泄露 String是Java中一个比较基础的类,每一个开发人员都会经常接触到.而且,String也是面试中经常会考的知识点.String有很多方法,有些方 ...

  7. inputstreamreader未关闭会导致oom_ThreadLocal 一定会导致内存泄露?

    在面试的时候,ThreadLocal作为高并发常用工具经常会被问到.而面试官比较喜欢问的问题有以下两个: 1.ThreadLocal是怎么实现来保证每个线程的变量副本的. 2.ThreadLocal的 ...

  8. terminatethread导致内存泄露

    terminatethread导致内存泄露,waitforsingleobject又容易导致UI卡死,真头疼 听过无数次不要TerminateThread,只是工作中常用,貌似也没有什么问题.今天在高 ...

  9. 什么是内存溢出与内存泄露,几种常见导致内存泄露的写法

    最近朋友推荐了一篇关于内存溢出与内存泄漏的文章,感觉写的还不错,于是便在网上搜索了一番,对这块进行了加固,发现自己之前写的代码也存在一些内存泄漏的风险,所以弄懂内存泄漏与内存溢出是很有利于我们提高代码 ...

最新文章

  1. CentOS 7 相关命令
  2. 中文短文本相似度:WMD
  3. CMake常见指令总结
  4. Grafana+Prometheus系统监控之MySql
  5. C学习杂记(六)%2.0f打印输出宽度
  6. html实现动态多表单输入,使用javascript动态编辑多个相同的HTML表单
  7. 高考语文再现奇葩作文题!大数据分析高考作文,看看哪年最坑爹?
  8. ArcGIS设置默认金字塔弹出框
  9. 替换过的mysql能找回来_MySQL 误操作后数据恢复(update,delete忘加where条件)
  10. 【IoT】产品设计:硬件产品开发流程之ID与MD设计(文字)
  11. Android Studio GPX文件解析显示地图轨迹和海拔示意(模拟沿轨迹前进)
  12. unity开发微信小游戏1
  13. python电商项目介绍_django打造电商项目
  14. 美军回应网传UFO:视频为真 现有人类技术无法达到
  15. 腾讯手游助手吃鸡一直服务器繁忙,腾讯手游助手吃鸡手游常见问题解决办法介绍...
  16. 利用拉勾网爬取的数据查看当前的数据分析岗的市场行情
  17. Non-Reflecting Boundary Conditions in OpenFOAM
  18. Java基础入门第二章
  19. 注册页面跳转登入页面无法正常显示返回的是页面名称的字符串,而不是页面
  20. Git本地代码同步到Github远程仓库

热门文章

  1. 全面讲解Tomcat下SSL证书的配置(五)
  2. Matlab中firpm函数设计具有非对称衰减的 FIR 带通滤波器
  3. gps-sdr-sim c语言程序,用SDR实时伪造GPS信号
  4. Richardson成熟度模型
  5. 【教程】Altium Designer 6.9导出库和更新PCB器件时,镂空字符(Inverted)框变大的解决办法
  6. Error:(4, 35) java: 程序包org.springframework.context不存在
  7. 多元线性回归最小二乘法及其应用
  8. 使用禅道进行测试管理
  9. 加密算法五虎上将之DES
  10. PATL2_026 小字辈