Re: way to catch g_malloc failures



Jared Davis <abiword aiksaurus com> writes:  
> I can handle an out-of-memory condition fairly well in most cases. 

But none of the GTK internals handle it - if a GTK function runs out
of memory and g_malloc() returned NULL it would just segfault before
returning flow of control to your code.  g_malloc() is assumed to
succeed 100% of the time by GTK. Otherwise every last GTK function
would return an error code, and everyone's code would be a giant nest
of error handling hell:

 retry_label:

   label = gtk_label_new ();

   if (label == NULL) {
      free_some_memory ();
      goto retry_label;
   }
 
 retry_text:

   if (!gtk_label_set_text (label, "Foo")) {
      free_some_memory ();     
      goto retry_text;
   }

etc., etc. - no one would ever do this, so everyone's code would just
fail ungracefully on out of memory. That's why g_malloc() simply exits
cleanly.

In GLib 2.0 (1.3.x for now) you can set a malloc handler that can try
to find more memory if an initial malloc() fails. However, you must
either return non-NULL from g_malloc() or exit, there is no way to
return NULL from g_malloc() even in 2.0, only a way to try to recover
by freeing memory.

There is a g_try_malloc() that will return NULL on failure in 2.0, but
GTK does not use it internally except for potentially large memory
allocations whose size depends on external data (e.g. when loading a
file). Those are the only cases where trying to handle out of memory
really makes sense.

There have been numerous huge threads on whether all this is right on
gtk-devel-list and probably this list too, check the archives. I think
it's safe to say you'll get zero interest from the GTK maintainers in
changing 2.0 behavior - adding the malloc handler feature and
g_try_malloc() was the extent of changes they were willing to make.

BTW, there is no way to throw C++ exceptions through C code, you will
get memory leaks, corruption of global state, and other hosage. So the
throwBadAlloc() idea doesn't work even in 2.0 when you have the malloc
handler function. To throw exceptions everything on the call stack
must be exception-safe, which is really only possible using C++
destructors.

Havoc



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]