Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > Handing initialization failures

Reply
Thread Tools

Handing initialization failures

 
 
Максим Фомин
Guest
Posts: n/a
 
      09-16-2011
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.
 
Reply With Quote
 
 
 
 
James Kuyper
Guest
Posts: n/a
 
      09-16-2011
On 09/16/2011 02:42 PM, Максим Фомин 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.


Set all of the pointers to null at start.
If any allocation fails, free ALL of the pointers.
Situations like this are part of the reason why the standard allows null
pointers to be passed to free().
 
Reply With Quote
 
 
 
 
Ben Bacarisse
Guest
Posts: n/a
 
      09-16-2011
Максим Фомин <> writes:

> 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.


One solution is to initialise the struct first so that all the pointers
are null. Then you can safely free everything because free(0) is a
no-op. One way to do this is to keep a

static struct Container zero;

so that you can do

struct Container *sp = malloc(sizeof *sp);
if (sp != NULL) {
*sp = zero;
if ((sp->res1 = malloc(sizeof *sp->res1)) == NULL)
goto clean_up;
/* etc. */
}

If the 'res' members were in an array you would not need to do this --
the code is often simpler with arrays:

for (i = 0; i < n; i++)
if ((sp->res[i] = malloc(sizeof *sp->res[i])) == NULL) {
for (j = 0; j < i; j++)
free(sp->res[j]);
break;
}

--
Ben.
 
Reply With Quote
 
ImpalerCore
Guest
Posts: n/a
 
      09-16-2011
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.
 
Reply With Quote
 
jacob navia
Guest
Posts: n/a
 
      09-16-2011
Le 16/09/11 20:42, Максим Фомин a écrit :
> 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.


Besides the other answers you got consider using a garbage collector.
All these problems go away with that solution. (Others may appear).

Under windows you can use the gc dll with any compiler, as in linux.

 
Reply With Quote
 
Ian Collins
Guest
Posts: n/a
 
      09-16-2011
On 09/17/11 07:45 AM, jacob navia wrote:
> Le 16/09/11 20:42, Максим Фомин a écrit :
>> 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.

>
> Besides the other answers you got consider using a garbage collector.
> All these problems go away with that solution. (Others may appear).


Only if the resource in question is memory.

--
Ian Collins
 
Reply With Quote
 
Malcolm McLean
Guest
Posts: n/a
 
      09-16-2011
On Sep 16, 9: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.
>

I just write

res1 = allocateresource1();
if(res1 == NULL)
goto outofmemory;

....
outofmemory:
cleanupeverything;
return NULL;

You sometimes have to be careful to set all the pointers to NULL, so
that they can be either passed to free harmlessly or detected as
unallocated and not freed.
--
Basic algorithms, in C. Full JPEG codec.
http://www.malcolmmclean.site11.com/www
 
Reply With Quote
 
Максим Фомин
Guest
Posts: n/a
 
      09-17-2011
On Sep 16, 11:20*pm, James Kuyper <jameskuy...@verizon.net> wrote:
>
> > 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.

>
> Set all of the pointers to null at start.
> If any allocation fails, free ALL of the pointers.
> Situations like this are part of the reason why the standard allows null
> pointers to be passed to free().


Actually that resources are not dynamic memory, they are allocated in
the way struct Container does, but I can make allocation functions
behave like free(NULL) does.
 
Reply With Quote
 
Paul N
Guest
Posts: n/a
 
      09-17-2011
On Sep 16, 7: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.


One possible approach - no-one else has mentioned it, perhaps that
suggests it's no good - would be to have nested ifs. For instance,
something like:

struct Container *container_alloc(void) {
// allocate container c itself
c -> res1 = whatever
if (worked) {
c -> res2 = whatever
if (worked) {
return c; }
free res2 }
free res1
return NULL;
}
 
Reply With Quote
 
Nobody
Guest
Posts: n/a
 
      09-17-2011
On Fri, 16 Sep 2011 11:42:36 -0700, Максим Фомин wrote:

> What is best way to deal whis this?


C++ and RAII

> 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.


One solution not mentioned so far is:

obj = obj_alloc();
if (!obj)
goto fail0;
obj->res1 = res1_alloc();
if (!obj->res1)
goto fail1;
obj->res2 = res2_alloc();
if (!obj->res2)
goto fail2;
...
return obj; /* success */
...
fail3:
res2_free(obj->res2);
fail2:
res1_free(obj->res1);
fail1:
obj_free(obj);
fail0:
return NULL;

Personally, I'd just go with having all of the _free() functions ignore
NULL pointers, so that you can legitimately call the top-level obj_free()
function on a partially-constructed object.

 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
PIX DCHPD handing out multiple IPs to single MAC gord.veri@gmail.com Cisco 3 03-02-2006 06:03 PM
error handing =?Utf-8?B?Y2FzYXVib24=?= ASP .Net 1 06-22-2005 07:52 PM
API for Handing Word Document Dips Java 7 05-20-2005 03:45 PM
Query on handing array of object . June Moore Java 5 01-15-2004 07:22 AM
Issues with handing server events... AC ASP .Net 2 12-19-2003 02:08 PM



Advertisments
 



1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57