Re: A solution for the allocation failures problem



jacob navia wrote:
1:
It is not possible to check EVERY malloc result within complex software.

Why not? It's no harder than checking every fopen() for
success -- or is that another impossibility?

2:
The reasonable solution (use a garbage collector) is not possible for
whatever reasons.

Garbage collection (when it works) eases the memory management
problem by relieving the programmer of the need to call free().
But collecting all the garbage does not imply that every malloc()
will succeed! In fact, a collector that cannot relocate the non-
garbage is likely to increase fragmentation and produce allocation
failures when a free()-as-soon-as-possible strategy would not.

3:
A solution like the one proposed by Mr McLean (aborting) is not
possible for software quality reasons. The program must decide
if it is possible to just abort() or not.

Solution:

1) At program start, allocate a big buffer that is not used
elsewhere in the program. This big buffer will be freed when
a memory exhaustion situation arises, to give enough memory
to the error reporting routines to close files, or otherwise
do housekeeping chores.

This is a reasonable thing to try, and has been tried
often. The hard part is choosing a value for "big:" too little
and there's not enough for the cleanup activity, too much and
you provoke allocation failures that don't need to happen.

4:
Using the above solution the application can abort if needed, or
make a long jump to a recovery point, where the program can continue.

The problems of longjmp() are well understood. It's possible
to use it effectively, but the programmers who write functions
"between" the setjmp() and the longjmp() must be constantly aware
that they might not get a chance to clean up:

char *this = dup(getenv("THIS"));
char *that = dup(getenv("THAT"));
printf ("THIS = %s, THAT = %s\n", this, that);
free (this);
free (that);

See the memory leak? If the second dup() eventually calls
longjmp() and returns to an ancestor of this code, the
memory allocated to `this' is never freed.

It's possible to work around this problem: various people
have put together macro packages that imitate a try/finally
discipline, for example. But the language itself gives little
help, and the compilers won't warn if somebody forgets (for
example, when a function that originally didn't need cleanup
acquires such a need during maintenance). Error recovery
based on longjmp() is do-able, but difficult.

--
Eric.Sosman@xxxxxxx
.



Relevant Pages

  • Re: dgemm subroutine in BLAS - I think Ive cracked the difference, please confirm
    ... > see what I'm talking about), so in the current state of memory allocation, ... padding for performance reasons - a memory subsystem might work much better ... so you would perform a 1024x1024 FFT on a 1025x1024 array ...
    (comp.lang.fortran)
  • Re: xmalloc string functions
    ... a bit over three quarters of the memory, Lotus Notes, another email ... I have good reasons for using multiple email clients ... propagating the error conditions back to the caller. ... event processing against oom exceptions either. ...
    (comp.lang.c)
  • Re: xmalloc string functions
    ... I, on the other hand, can be running three VMs eating up a bit over three quarters of the memory, Lotus Notes, another email client (yes, I have good reasons for using multiple email clients simultaneously) and several other applications. ... propagating the error conditions back to the caller. ... Linux and several versions of Windows. ...
    (comp.lang.c)
  • Re: Future Risc
    ... |> Any architecture with hw support for decimal fp is pretty CISCy indeed. ... For various reasons, I have restarted my ... simplified the code - I could do the same with the rounding, ...
    (comp.arch)
  • Re: CString problem!!!
    ... I know for sure that malloc() returns NULL when allocation fails. ... don't see a good reason to convert here, for the reasons you point out below. ... The reason was the OP wanting to do a Unicode string writing to ...
    (microsoft.public.vc.mfc)