干净退出 - 建议 - C版 [英] clean exit - suggestion - C version

查看:53
本文介绍了干净退出 - 建议 - C版的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

您好,


这个问题在comp.lang.c ++中被问到,答案涉及使用

对象,其中的析构函数在获取时自动被调用超出

范围,但我期待的建议不涉及使用

对象。所以这里又是一个问题。


我的功能如下:


void fnc(){

char * mem1,* mem2,* mem3,* mem4;

FILE * fp1;

//很多代码......

/ / mem1,2,3,4已分配

//大量代码和条件检查

if(condition_failed)

{

// blah blah

//免费mem1,mem2,mem3,mem4

返回;

}


if(condition2_failed)

{

// blah blah

//免费mem1,mem2,.. 。

fclose(fp1);

返回;

}


//这里结束例程(干净的退出代码):

//免费mem1,mem2,mem3,mem4

}


通常,我通过将__try()中的大部分代码

和_finally()块中的干净退出代码放在

清除退出代码中,我将使用编译器特定的解决方案调用__leave。


或者使用标签然后转到cle an_exit


除了goto或编译器特定的解决方案之外还有更好的方法吗?


-

Elias

解决方案

" lallous" < LA ***** @ lgwm.org>在消息中写道

news:bt ************ @ ID-161723.news.uni-berlin.de ...

你好,
...
我的功能如下:

void fnc(){
char * mem1,* mem2,* mem3,* mem4;
FILE * fp1;
//很多代码......
// mem1,2,3,4已分配
//大量代码和条件检查
如果(condition_failed)
// blah blah
//免费mem1,mem2,mem3,mem4
返回;
}

如果(condition2_failed)
// blah blah
//免费mem1,mem2,...
fclose(fp1);
返回;
}

//这里的例程结束(干净的退出代码):
//免费mem1,mem2,mem3,mem4
}

通常情况下,我会使用编译器特定的解决方案,将大部分
代码放在__try()中,然后将干净的退出代码放在_finally()块中,然后到达
干净的退出代码,我将调用__leave。

或者使用标签然后转到clean_exit

任何更好的方法,oth比goto或编译器特定的解决方案?




一个永无止境的故事...你会得到那么多回复那么多的海报

是在Usenet ;-)


我的首选解决方案是:


void fnc(无效)

{

char * const mem1 = something_that_allocates_mem1();

if(mem1)

{

char * const mem2 = something_that_allocates_mem2 ();

if(mem2)

{

/ * ...等。 * /

免费(mem2);

}

免费(mem1);

}

}


这有IMO的两个主要优点:

1.更清楚,变量仅在何时何地被声明它们是实际使用的


2.内存按照相反的分配顺序释放,这通常被认为是一种很好的做法(尽管是b $ b)它应该没有区别。)


另一方面,如果你有太多的

变量需要清除它可能会有点麻烦。


但正如我所说,这只是一种风格问题。使用您认为最好的(或您的公司编码指南要求您)。


Peter


Peter Pichler写道:


lallous < LA ***** @ lgwm.org>在消息中写道
新闻:bt ************ @ ID-161723.news.uni-berlin.de ...

...
void fnc(){
char * mem1,* mem2,* mem3,* mem4;
FILE * fp1;
//很多代码......
// mem1,2,3,4已分配
//大量代码和条件检查
if(condition_failed)
{
//等等等等等等等等等等等(条件2失效)
{
// blah blah
//免费mem1,mem2,...
fclose(fp1);
返回;
}
// //例程结束(干净退出代码):
//免费mem1,mem2,mem3,mem4
}


.... snip ...
一个永无止境的故事......你会得到许多回复,因为Usenet上有很多
海报;-)

我最喜欢的解决方案是:

void fnc (void)
{char / const mem1 = something_that_allocates_mem1();
if(mem1)
{
c har * const mem2 = something_that_allocates_mem2();
if(mem2)
{
/ * ...等。 * /
免费(mem2);
}
免费(mem1);
}
}




和我的版本是:


void fnc(无效)

{

char * cp1;

char * cp2;

char * cp3;

/ *如果需要* /


if(!(cp1 = malloc(CP1SIZE)))goto cp1fail;

else if(!(cp2 = malloc(CP2SIZE)))goto cp2fail;

else if(!(cp3 = malloc( CP3SIZE)))转到cp3fail;

else {

/ *他们都工作 - 使用em * /

}

cp3fail:

免费(cp3);

cp2fail:

免费(cp2);

cp1fail:

免费(cp1);

}


可轻松扩展/压缩到所需的东西。对于

免费清理,我们可以重做这个来消除这些,并且

只需对cpN使用NULL初始化,但上面的

组织将处理更复杂的场景。


-

查克F(cb********@yahoo.com)(cb *** *****@worldnet.att.net)

可用于咨询/临时嵌入式和系统。

< http://cbfalconer.home.att.net> ;使用worldnet地址!


CBFalconer< cb ******** @ yahoo.com>在消息新闻中写道:< 40 *************** @ yahoo.com> ...

Peter Pichler写道:


lallous < LA ***** @ lgwm.org>在消息中写道
新闻:bt ************ @ ID-161723.news.uni-berlin.de ...

...
void fnc(){
char * mem1,* mem2,* mem3,* mem4;
FILE * fp1;
//很多代码......
// mem1,2,3,4已分配
//大量代码和条件检查
if(condition_failed)
{
//等等等等等等等等等等等(条件2失效)
{
// blah blah
//免费mem1,mem2,...
fclose(fp1);
返回;
}
// //例程结束(干净的退出代码):
//免费mem1,mem2,mem3,mem4
}


... snip ... < blockquote class =post_quotes>
一个永无止境的故事...你会在Usenet上得到那么多的回复海报;-)

我的首选解决方案是:

void fnc(void)
{char / const mem1 = something_that_allocates_m em1();
if(mem1)
{
char * const mem2 = something_that_allocates_mem2();
if(mem2)
{
/ *。 ..等等。 * /
免费(mem2);
}
免费(mem1);
}
}



和我的版本是:

void fnc(void)
{* char * cp1;
char * cp2;
char * cp3;
/ *根据需要* /

if(!(cp1 = malloc(CP1SIZE)))goto cp1fail;
if if(!(cp2 = malloc(CP2SIZE)))goto cp2fail;
否则if(!(cp3 = malloc(CP3SIZE)))goto cp3fail;
else {
/ *他们都工作 - 使用em * /
}
cp3fail:
免费(cp3);
cp2fail:
免费(cp2);
cp1fail:
免费(cp1);
}

这很容易扩展/压缩到所需的东西。对于免费清理我们可以重新设计以消除这些内容,并且只需对cpN使用NULL初始化,但上述组织将适用于更复杂的场景。




我的问题是:

1)我分配了大量资源(内存,文件......)

2)for除了分配失败之外的一些条件代码将需要退出并清理,但不是每次清理并且重复清理代码而需要清理代码,清理代码必须写一次

并通过某些技巧多次调用,例如''goto''


//这里分配了资源

//这里有条件

if(失败)

{

//清理代码

}

//一些代码

//某些条件

if(failed2)

{

//与上述相同的清理代码.....

}


Hello,

This question was asked in comp.lang.c++ and the answers involved the use of
objects whose destructors are automatically called when getting out of
scope, however I was expecting suggestions that doesn''t involve the use of
objects. So here is the question again.

I have a function like:

void fnc() {
char *mem1, *mem2, *mem3, *mem4;
FILE *fp1;
// lots of code...
// mem1, 2, 3, 4 got allocated
// lots of code and condition checks
if (condition_failed)
{
// blah blah
// free mem1, mem2, mem3, mem4
return;
}

if (condition2_failed)
{
// blah blah
// free mem1, mem2, ...
fclose(fp1);
return;
}

// here the end of routine (clean exit code):
// free mem1, mem2, mem3, mem4
}

Usually, I would use compiler specific solution by putting most of the code
in __try() and the clean exit code in _finally() block then to reach the
clean exit code I would invoke __leave.

Or use lables and then goto clean_exit

Any better way, other than goto or compiler specific solution?

--
Elias

解决方案

"lallous" <la*****@lgwm.org> wrote in message
news:bt************@ID-161723.news.uni-berlin.de...

Hello,
...
I have a function like:

void fnc() {
char *mem1, *mem2, *mem3, *mem4;
FILE *fp1;
// lots of code...
// mem1, 2, 3, 4 got allocated
// lots of code and condition checks
if (condition_failed)
{
// blah blah
// free mem1, mem2, mem3, mem4
return;
}

if (condition2_failed)
{
// blah blah
// free mem1, mem2, ...
fclose(fp1);
return;
}

// here the end of routine (clean exit code):
// free mem1, mem2, mem3, mem4
}

Usually, I would use compiler specific solution by putting most of the code in __try() and the clean exit code in _finally() block then to reach the
clean exit code I would invoke __leave.

Or use lables and then goto clean_exit

Any better way, other than goto or compiler specific solution?



A never ending story... You will get that many replies as many posters there
are on Usenet ;-)

My prefered solution is:

void fnc (void)
{
char * const mem1 = something_that_allocates_mem1();
if (mem1)
{
char * const mem2 = something_that_allocates_mem2();
if (mem2)
{
/* ...etc. */
free(mem2);
}
free(mem1);
}
}

This has, IMO, two main advantages:
1. It''s much clearer, variables are only declared where and when they are
actually used.
2. Memory is freed in the reverse order of allocation, which is usually
considered a good practice (though it should make no difference).

On the other hand, it may get a bit cumbersome if you have too many
variables to clear.

But as I said, it is all merely a matter of style. Use what you think is the
best (or your company coding guidelines dictate you).

Peter


Peter Pichler wrote:


"lallous" <la*****@lgwm.org> wrote in message
news:bt************@ID-161723.news.uni-berlin.de...

...
I have a function like:

void fnc() {
char *mem1, *mem2, *mem3, *mem4;
FILE *fp1;
// lots of code...
// mem1, 2, 3, 4 got allocated
// lots of code and condition checks
if (condition_failed)
{
// blah blah
// free mem1, mem2, mem3, mem4
return;
}

if (condition2_failed)
{
// blah blah
// free mem1, mem2, ...
fclose(fp1);
return;
}

// here the end of routine (clean exit code):
// free mem1, mem2, mem3, mem4
}

.... snip ...
A never ending story... You will get that many replies as many
posters there are on Usenet ;-)

My prefered solution is:

void fnc (void)
{
char * const mem1 = something_that_allocates_mem1();
if (mem1)
{
char * const mem2 = something_that_allocates_mem2();
if (mem2)
{
/* ...etc. */
free(mem2);
}
free(mem1);
}
}



and my version is:

void fnc(void)
{
char *cp1;
char *cp2;
char *cp3;
/* as needed */

if (!(cp1 = malloc(CP1SIZE))) goto cp1fail;
else if (!(cp2 = malloc(CP2SIZE))) goto cp2fail;
else if (!(cp3 = malloc(CP3SIZE))) goto cp3fail;
else {
/* they all worked - use em */
}
cp3fail:
free(cp3);
cp2fail:
free(cp2);
cp1fail:
free(cp1);
}

which is easily extended/compressed to the things needed. For
cleanup with free we can rework this to eliminate the gotos and
simply use NULL initializations for the cpN, but the above
organization will work with more complex scenarios.

--
Chuck F (cb********@yahoo.com) (cb********@worldnet.att.net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home.att.net> USE worldnet address!


CBFalconer <cb********@yahoo.com> wrote in message news:<40***************@yahoo.com>...

Peter Pichler wrote:


"lallous" <la*****@lgwm.org> wrote in message
news:bt************@ID-161723.news.uni-berlin.de...

...
I have a function like:

void fnc() {
char *mem1, *mem2, *mem3, *mem4;
FILE *fp1;
// lots of code...
// mem1, 2, 3, 4 got allocated
// lots of code and condition checks
if (condition_failed)
{
// blah blah
// free mem1, mem2, mem3, mem4
return;
}

if (condition2_failed)
{
// blah blah
// free mem1, mem2, ...
fclose(fp1);
return;
}

// here the end of routine (clean exit code):
// free mem1, mem2, mem3, mem4
}


... snip ...


A never ending story... You will get that many replies as many
posters there are on Usenet ;-)

My prefered solution is:

void fnc (void)
{
char * const mem1 = something_that_allocates_mem1();
if (mem1)
{
char * const mem2 = something_that_allocates_mem2();
if (mem2)
{
/* ...etc. */
free(mem2);
}
free(mem1);
}
}



and my version is:

void fnc(void)
{
char *cp1;
char *cp2;
char *cp3;
/* as needed */

if (!(cp1 = malloc(CP1SIZE))) goto cp1fail;
else if (!(cp2 = malloc(CP2SIZE))) goto cp2fail;
else if (!(cp3 = malloc(CP3SIZE))) goto cp3fail;
else {
/* they all worked - use em */
}
cp3fail:
free(cp3);
cp2fail:
free(cp2);
cp1fail:
free(cp1);
}

which is easily extended/compressed to the things needed. For
cleanup with free we can rework this to eliminate the gotos and
simply use NULL initializations for the cpN, but the above
organization will work with more complex scenarios.



My question was:
1)I have allocated lots of resources (memory, files, ...)
2)for some conditions other than allocation failures the code will
have to exit and clean up, but instead of cleaning up everytime and
repeating the clean up code, the clean up code must be written once
and called many times by some technique such as ''goto''

// here resources are allocated
// here some condition
if (failed)
{
// cleanup code
}
// some code
// some condition
if (failed2)
{
// same cleanup code as above.....
}


这篇关于干净退出 - 建议 - C版的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆