在初始化C中的多个资源的函数中处理错误(清理和中止)的一些好方
首先,如果有人可以重新提出问题以使其更清楚,请执行.
C编程中常见的情况是要按特定顺序初始化/分配多个资源.每个资源都是后续资源初始化的先决条件.如果其中一个步骤失败,则必须取消分配先前步骤的剩余资源.理想的伪代码(利用神奇的通用pure-unobtainium clean_up_and_abort()函数)看起来大致如下: err=alloc_a() if(err) clean_up_and_abort() err=alloc_b() if(err) clean_up_and_abort() err=alloc_c() if(err) clean_up_and_abort() // ... profit() 我已经看到了几种处理这种方法的方法,所有这些方法似乎都有很大的缺点,至少在人们倾向于考虑“良好实践”方面. 在处理这种情况时,构造代码的最可读和最不容易出错的方法是什么?效率是优选的,但为了便于阅读,可以牺牲合理的效率.请列出优点和缺点.欢迎讨论多种方法的答案. 我们的目标是希望最终得到一套解决这个问题的几种首选方法. 我将从我已经看过的一些方法开始,请对它们进行评论并添加其他方法. 解决方法
4:全局变量,哇哦!因为每个人都喜欢全局变量,就像他们喜欢goto一样.但严重的是,如果将变量的范围限制为文件范围(使用static关键字),那就不是那么糟糕了.附注:清理函数接收/返回错误代码不变,以便在init_function中整理代码.
static A *a = NULL; static B *b = NULL; static C *c = NULL; uint32_t cleanup( uint32_t errcode ) { if ( c ) dealloc_c(&c); if ( b ) dealloc_b(&b); if ( a ) dealloc_a(&a); return errcode; } uint32_t init_function( void ) { if ( alloc_a(&a) != SUCCESS ) return cleanup(INIT_FAIL_A); if ( alloc_b(&b) != SUCCESS ) return cleanup(INIT_FAIL_B); if ( alloc_c(&c) != SUCCESS ) return cleanup(INIT_FAIL_C); profit(a,b,c); return INIT_SUCCESS; } 5:人造OOP.对于那些无法处理真相的人(全局变量在C程序中实际有用),您可以采用C方法. C获取所有全局变量,将它们放入结构中,并将它们称为“成员”变量.不知怎的,这让每个人都开心. 诀窍是将指向结构的指针传递给所有函数,作为第一个参数. C在幕后执行此操作,在C中您必须明确地执行此操作.我调用指针,以避免与此冲突/混淆. // define a class (uhm,struct) with status,a cleanup method,and other stuff as needed typedef struct stResources { char *status; A *a; B *b; C *c; void (*cleanup)(struct stResources *that); } stResources; // the cleanup method frees all resources,and frees the struct void cleanup( stResources *that ) { if ( that->c ) dealloc_c( &that->c ); if ( that->b ) dealloc_b( &that->b ); if ( that->a ) dealloc_a( &that->a ); free( that ); } // the init function returns a pointer to the struct,or NULL if the calloc fails // the status member variable indicates whether initialization succeeded,NULL is success stResources *init_function( void ) { stResources *that = calloc( 1,sizeof(stResources) ); if ( !that ) return NULL; that->cleanup = cleanup; that->status = "Item A is out to lunch"; if ( alloc_a( &that->a ) != SUCCESS ) return that; that->status = "Item B is never available when you need it"; if ( alloc_b( &that->b ) != SUCCESS ) return that; that->status = "Item C is being hogged by some other process"; if ( alloc_c( &that->c ) != SUCCESS ) return that; that->status = NULL; // NULL is success return that; } int main( void ) { // create the resources stResources *resources = init_function(); // use the resources if ( !resources ) printf( "Buy more memory alreadyn" ); else if ( resources->status != NULL ) printf( "Uhm yeah,so here's the deal: %sn",resources->status ); else profit( resources->a,resources->b,resources->c ); // free the resources if ( resources ) resources->cleanup( resources ); } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |