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与冗余异常处理应该被严厉禁止。
return导致内存泄露。C函数中不要有多次return,以及其解决方法。goto的用法。相关推荐
- ajax回调函数中不能触发input[type='file']事件的解决方法
今天在做文件上传遇到一个问题,在ajax回调成功后触发input[type='file']元素的事件时始终不能弹出文件选择对话框 ,于是开始各种问题的排除,最终我发现在ajax 异步提交不行,要同步提 ...
- VC 2010的MFC函数,CMFCVisualManager::GetInstance()可能导致内存泄露
今天在网上看到一篇文章,关于CMFCVisualManager的内存泄露问题( 链接是 http://zhanyonhu.blog.163.com/blog/static/16186044201132 ...
- pthread_create会导致内存泄露
这几天一直在调试一个系统,系统的功能就是定时发送数据.接收数据然后解析收到的数据,转换成一定的格式存入数据库中.我为了并发操作,所以每接收到一个数据包,就调用pthread_create函数创建一个默 ...
- android如何避免内存泄露,Android开发中应该避免的内存泄露
一.背景和目的: 目前许多开发人员在Android开发过程中,较少关注实现细节和内存使用,容易会造成内存泄露,导致程序OOM. 本文会通过代码向大家介绍在Android开发过程中常见的内存泄露. 二. ...
- 使用ThreadLocal不当可能会导致内存泄露
使用ThreadLocal不当可能会导致内存泄露 基础篇已经讲解了ThreadLocal的原理,本节着重来讲解下使用ThreadLocal会导致内存泄露的原因,并讲解使用ThreadLocal导致内存 ...
- String 使用不当可能导致内存泄露
转载自 String 使用不当可能导致内存泄露 String是Java中一个比较基础的类,每一个开发人员都会经常接触到.而且,String也是面试中经常会考的知识点.String有很多方法,有些方 ...
- inputstreamreader未关闭会导致oom_ThreadLocal 一定会导致内存泄露?
在面试的时候,ThreadLocal作为高并发常用工具经常会被问到.而面试官比较喜欢问的问题有以下两个: 1.ThreadLocal是怎么实现来保证每个线程的变量副本的. 2.ThreadLocal的 ...
- terminatethread导致内存泄露
terminatethread导致内存泄露,waitforsingleobject又容易导致UI卡死,真头疼 听过无数次不要TerminateThread,只是工作中常用,貌似也没有什么问题.今天在高 ...
- 什么是内存溢出与内存泄露,几种常见导致内存泄露的写法
最近朋友推荐了一篇关于内存溢出与内存泄漏的文章,感觉写的还不错,于是便在网上搜索了一番,对这块进行了加固,发现自己之前写的代码也存在一些内存泄漏的风险,所以弄懂内存泄漏与内存溢出是很有利于我们提高代码 ...
最新文章
- CentOS 7 相关命令
- 中文短文本相似度:WMD
- CMake常见指令总结
- Grafana+Prometheus系统监控之MySql
- C学习杂记(六)%2.0f打印输出宽度
- html实现动态多表单输入,使用javascript动态编辑多个相同的HTML表单
- 高考语文再现奇葩作文题!大数据分析高考作文,看看哪年最坑爹?
- ArcGIS设置默认金字塔弹出框
- 替换过的mysql能找回来_MySQL 误操作后数据恢复(update,delete忘加where条件)
- 【IoT】产品设计:硬件产品开发流程之ID与MD设计(文字)
- Android Studio GPX文件解析显示地图轨迹和海拔示意(模拟沿轨迹前进)
- unity开发微信小游戏1
- python电商项目介绍_django打造电商项目
- 美军回应网传UFO:视频为真 现有人类技术无法达到
- 腾讯手游助手吃鸡一直服务器繁忙,腾讯手游助手吃鸡手游常见问题解决办法介绍...
- 利用拉勾网爬取的数据查看当前的数据分析岗的市场行情
- Non-Reflecting Boundary Conditions in OpenFOAM
- Java基础入门第二章
- 注册页面跳转登入页面无法正常显示返回的是页面名称的字符串,而不是页面
- Git本地代码同步到Github远程仓库
热门文章
- 全面讲解Tomcat下SSL证书的配置(五)
- Matlab中firpm函数设计具有非对称衰减的 FIR 带通滤波器
- gps-sdr-sim c语言程序,用SDR实时伪造GPS信号
- Richardson成熟度模型
- 【教程】Altium Designer 6.9导出库和更新PCB器件时,镂空字符(Inverted)框变大的解决办法
- Error:(4, 35) java: 程序包org.springframework.context不存在
- 多元线性回归最小二乘法及其应用
- 使用禅道进行测试管理
- 加密算法五虎上将之DES
- PATL2_026 小字辈