免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 6242 | 回复: 11

关于异常和资源释放的问题! [复制链接]

论坛徽章:
0
发表于 2008-08-11 14:58 |显示全部楼层
5可用积分
如果一个方法中分配了资源,而且方法中调用了可能抛出异常的其他方法,如果在应用的最上层,即调用该方法的方法,或者说,调用链中的最高层,有异常捕获代码段,那么,如果在这个方法中不进行异常捕获并在捕获代码中释放资源,将导致资源无法释放!
比如:
func_lower();//抛出异常的函数
func(){ int * a=new int[100]; func_lower();}
func_upper(){try{func();}catch(e&){...}}

如果func_lower抛出了异常,那么将导致func在中在堆中分配的内存丢失,也就是说这种情况,我必须先捕获异常,在抛出同样的异常,来传播异常!

我的理解是不是正确的?关于异常和资源之间的关系,我们应该注意些什么?谢谢!

最佳答案

查看完整内容

要么捕获异常并处理(释放资源,处理异常或者向外重新抛出异常)要么把资源封装在类对象中,让其自动释放,此时可以不处理异常,直接让外层进行异常处理

论坛徽章:
0
发表于 2008-08-11 14:58 |显示全部楼层
要么捕获异常并处理(释放资源,处理异常或者向外重新抛出异常)
要么把资源封装在类对象中,让其自动释放,此时可以不处理异常,直接让外层进行异常处理

论坛徽章:
0
发表于 2008-08-11 15:07 |显示全部楼层
为什么不在func里捕捉异常呢?
func(){
int * a=new int[100];
try
{
  func_lower();
}
catch(e&){...}
}

论坛徽章:
0
发表于 2008-08-11 15:08 |显示全部楼层
new 内存没有成功,你在new的时候要捕捉分配内存失败的异常,或在使用内存前要判断地址是否有效

论坛徽章:
0
发表于 2008-08-11 15:16 |显示全部楼层
原帖由 5毛党党员 于 2008-8-11 15:07 发表
为什么不在func里捕捉异常呢?
func(){
int * a=new int[100];
try
{
  func_lower();
}
catch(e&){...}
}


事实上,我认为,如果每一个函数或者方法中都去抛出捕获异常将是一件效率非常低的事情,只做必要的事情!所以,我现在所考虑的事情就是,什么情况下捕捉异常是必要的!

如果,我们在main函数中增加捕捉异常的代码,可以捕获任何地方跑出来的异常(可能除了全局变量的构造函数中跑出的异常);那么,其他地方,什么情况下捕捉异常是必要的,那么我就想到了如果分配堆中的资源,这种情况,系统不会主动释放资源,但如果有异常在服务代码中抛出,将导致资源无法释放,包括文件句柄无法关闭、内存无法释放等等!

如果,func中没有申请任何资源,那么我认为完全可以让异常向上传播,即使是直接传播到main函数(之间没有任何一个调用进行异常捕获),也是没有关系的!

论坛徽章:
0
发表于 2008-08-11 15:18 |显示全部楼层
原帖由 lanneret_sky 于 2008-8-11 15:08 发表
new 内存没有成功,你在new的时候要捕捉分配内存失败的异常,或在使用内存前要判断地址是否有效


如果使用stl中重载过的new,我认为在分配内存的函数中不需要捕获异常,当然,前提是之前没有资源需要释放!可以在上层捕获异常,呵呵,我认为!欢迎讨论!

论坛徽章:
0
发表于 2008-08-11 15:19 |显示全部楼层
1. 可以象2楼所说,贴近抛出异常处尝试捕捉。
2. 可以将需要动态获取内存的对象(本例为a)封装,在构造函数中动态分配,在析构函数中释放内存空间,这样,即使后续代码(本例为func_lower())抛出异常,该动态获得的内存也会随着封装对象离开作用域时的析构而自动释放。

论坛徽章:
0
发表于 2008-08-11 15:23 |显示全部楼层
原帖由 thinshootout 于 2008-8-11 15:19 发表
1. 可以象2楼所说,贴近抛出异常处尝试捕捉。
2. 可以将需要动态获取内存的对象(本例为a)封装,在构造函数中动态分配,在析构函数中释放内存空间,这样,即使后续代码(本例为func_lower())抛出异常,该动态 ...



是的,所以,我想可能很多原始的资源最好都进行封装,在栈中声明变量,在构造函数中申请堆中内存或打开句柄,析构函数释放内存,然后再变量生命周期结束后自动调用析构函数释放资源,这也就是只能指针诞生的一个目的!


关于异常,还有那些需要注意的地方???

论坛徽章:
0
发表于 2008-08-11 15:26 |显示全部楼层
我认为如果func_upper知道func的实现细节,完全可以做到在catch到异常的时候,正常释放内存。。。。
可是实际情况一般是func_upper不知道func怎么的细节,而是只能通过手册知道他会抛出什么异常。。。。这时的内存泄露就不是func_upper的责任了,而是要求func函数处理在他执行过程中可能产生的异常,处理内存

论坛徽章:
0
发表于 2008-08-11 15:30 |显示全部楼层
原帖由 5毛党党员 于 2008-8-11 15:26 发表
我认为如果func_upper知道func的实现细节,完全可以做到在catch到异常的时候,正常释放内存。。。。
可是实际情况一般是func_upper不知道func怎么的细节,而是只能通过手册知道他会抛出什么异常。。。。这时的 ...


你说的对呀!

谁干的事儿就要负责后果!我想跟大家讨论的就是捕获还是不捕获,什么情况下必须捕获!

捕获还是不捕获,这是个问题!呵呵
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP