ImpalerCore
9/16/2011 7:29:00 PM
On Sep 16, 2:42 pm, ?????? ????? <ma...@maxim-fomin.ru> wrote:
> Hello.
>
> I have a question regarding following problem. Let there is
>
> struct Container{
> void *buffer;
> resource1 *res1;
> resource2 *res2;
> ...
> resource_n *res_n;
>
> };
>
> pointer to which is return by function like container_alloc().
> Initialization of each member may fail and if last fails, and I need
> to free() all other initialized resources (otherwise there would be
> memory leakage). The situation become worse when any random "sub-
> resource" initialization may fail.
>
> What is best way to deal whis this? There is obvious solution to free
> all previous allocated resources within "if" test block of each
> element, however I am looking for a better solution.
Here is a possible way to deal with it.
\code untested
struct Container* container_alloc( size_of_buffer, r1, ..., rn )
{
struct Container* new_container = NULL;
bool alloc_failed = false;
new_container = malloc( sizeof (struct Container) );
if ( new_container )
{
new_container->buffer = !alloc_failed ?
malloc( size_of_buffer ) : NULL;
alloc_failed = new_container->buffer == NULL;
new_container->res1 = !alloc_failed ?
malloc( size_of_resource1 ) : NULL;
alloc_failed = new_container->res1 == NULL;
new_container->res2 = !alloc_failed ?
malloc( size_of_resource2 ) : NULL;
alloc_failed = new_container->res2 == NULL;
...
new_container->resN = !alloc_failed ?
malloc( size_of_resourceN ) : NULL;
alloc_failed = new_container->resN == NULL;
if ( alloc_failed )
{
free( new_container->buffer );
free( new_container->res1 );
free( new_container->res2 );
...
free( new_container->resN );
free( new_container );
new_container = NULL;
}
}
return new_container;
}
\endcode
The 'free' function allows freeing NULL pointers, so if an allocation
fault occurs, it should clean any partial resources that's been
allocated. Be sure to test it, as it's just off the top of my head.
Best regards,
John D.