Hi all
I am just wondering how most people implement cleanup in C functions.
In particular, if the function opens a number of resources, these need
to be released properly should an error occur at any point in the
function (as well as at the end if successful). C++ has exceptions,
the only way I can see to do this neatly in C is to use goto
statements. Is my method of implementing cleanup good, or are their
better ways. Here is an example, which uses the global errno to store
the error.
#define CLEANUP(err) ({errno = (err); goto cleanup})
int example_functio n()
{
SOMETYPE * a,b,c;
errno = 0;
if(!(a = malloc(sizeof(a ))))
CLEANUP(ENOMEM) ;
if(!(b = malloc(sizeof(b ))))
CLEANUP(ENOMEM) ;
if(!(c = malloc(sizeof(c ))))
CLEANUP(ENOMEM) ;
/* do something here */
cleanup:
if(a)
free(a);
if(b);
free(b);
if(c)
free(c);
if(errno)
return -1;
return 0;
}
I am just wondering how most people implement cleanup in C functions.
In particular, if the function opens a number of resources, these need
to be released properly should an error occur at any point in the
function (as well as at the end if successful). C++ has exceptions,
the only way I can see to do this neatly in C is to use goto
statements. Is my method of implementing cleanup good, or are their
better ways. Here is an example, which uses the global errno to store
the error.
#define CLEANUP(err) ({errno = (err); goto cleanup})
int example_functio n()
{
SOMETYPE * a,b,c;
errno = 0;
if(!(a = malloc(sizeof(a ))))
CLEANUP(ENOMEM) ;
if(!(b = malloc(sizeof(b ))))
CLEANUP(ENOMEM) ;
if(!(c = malloc(sizeof(c ))))
CLEANUP(ENOMEM) ;
/* do something here */
cleanup:
if(a)
free(a);
if(b);
free(b);
if(c)
free(c);
if(errno)
return -1;
return 0;
}
Comment