Re: glib CVS ?



On Mon, 26 Nov 2001, DINH V. Hoa wrote:

> On Sun, 25 Nov 2001 23:09:29 +0100 (CET)
> Tim Janik <timj gtk org> wrote:
> 
> > > > you could plug your own memory allocation routines into the glib memory
> > > > system (it has hooks that allow you to do so without patching). It will
> > > > be non-trivial however to gracefully recover from a failed memory 
> > > > allocation. Glib-2.0 has g_try_malloc() that you can use in your own
> > > > routines wherever it makes sense.
> > > 
> > > GString should be changed in order to use these
> > > g_try_realloc/g_try_malloc in order to recover from failed memory
> > > allocation, don't you think so ?
> > 
> > nope, GString's API doesn't have any provisions for reporting errors
> > ala "don't use me i couldn't allocate enough memory".
> 
> Couldn't it be added (I can do it and submit a patch)

nope, we're in API freeze already.

> > a good example of where g_try_malloc() is apropriate is the pixbuf
> > loading code, where out-of-mem is just another error condition
> > besides various other reasons for why an image couldn't get loaded,
> > and the allocation failing my very well be due to a broken image
> > file (say it told you to allocater space for 65535*65535 pixels).
> 
> The fact is that I am developing a library where I use
> GStrings and I can't exit the main program in case the memory
> allocation could not be done, and GString I will be manipulating
> can be enough large to induce out-of-memory errors.
> The program that will use this library should not exit on
> failure.

if out-of-mem is really a valid situation for your string manipulations
(usually things are messed up anyways if strings are allocated bigger
than memory available) you might want to use your own string handling
code.
note that GString can be quite inefficient if you use really huge strings,
e.g. when prepending a substring or a character to a 10MB string, you'll
effectively cause a 10MB memove().
in such situations it might be better to do things like:

GSList *slist, *word_list = NULL;
guint l = 0;
gchar *p, *s;
/* prepend words */
for (i = 0; i < n_words; i++)
  word_list = g_slist_prepend (word_list, words[i]);
/* finally, fold words into a real string */
for (slist = word_list; slist; slist = slist->next)
  l += strlen (slist->data);
s = p = g_try_malloc (l + 1);
if (!p)
  die ("not enough memory for string hackery");
for (slist = word_list; slist; slist = slist->next)
  {
    strcpy (p, slist->data);
    p += strlen (slist->data);
  }
g_slist_free (word_list);
g_print ("long string: %s\n", s);

> I really think that a library should not make a decision for
> the program that uses it do fail and to exit.

if we didn't do this, we'd have to pass up malloc errors through
virtually every public function, quite impossible if you think of
the usual call stack depth of the average gtk program.
considering that 99% of failing malloc()s are due to passing invalid args
(such as: 4 - 5) or the system being brought to a halt anyways, and that,
even if we handled g_malloc() failing more gracefully, things would usually
still blow up in other libs (e.g. xlib), checking NULL malloc() returns would
basically screw our API at little to no practical benefit.
since most programs would simply exit upon malloc()==NULL anyways - after
all, you can't pop up a dialog or somesuch in a situation like this - doing
the exit right away in g_malloc() is good enough for most apps.
(and those for which this falls short can still hook up their own memory
vtable).

---
ciaoTJ




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