alloca() portability

Dave Jones djones at megatest.UUCP
Fri Nov 16 10:20:09 AEST 1990


I don't see using alloca() as a high crime or a misdemeanor, but if you
are afraid of being castaway on the Isle of Enemy Computers, where alloca()
doesn't work right, you can use a hand-rolled memory allocation package
based on a separate stack.

That's handy anyway for applications whose data are naturally stackable (or
"treeable"), but whose flow of control does not precisely follow the
stacking and unstacking.

It goes like this:

The program obtains pointers into the stack ("stack-marks") and later
can free all the memory allocated after the mark was obtained, all it
one swell foop. Of course you will usually want the stack to be "virtual"
in the sense that it is not really one contiguous section of memory, and
it can grow without bound.

#include "ut_Lifo.h"

typedef struct
{
  int  block_size;    /* size of stack-sections */
  int  bytes_left;    /* number of bytes free top section */
  Lifo free_blocks;   /* list of free sections */
  Lifo blocks;        /* the stack per se. */

}Stack;

typedef struct
{
  char* block;        /* section of the stack on top at time of mark */
  int bytes_left;     /* top byte within that section. */
}Stack_mark;

The above implementation uses stack-sections all of one size, so the maximum
possible request must be known. For the application it was designed for
that is no problem. A little bit more overhead, and it could use
sections of undetermined size, perhaps growing them by a multiple of 3/2 or
2 as more sections are required. But the one I'm using is built for speed,
being approximately as fast as alloc() on the machines it runs on.

A note on longjmp's: The purpose of a longjmp is quite similar to
poping the memory-stack to a mark: It pops off a bunch of function-
activations all at one go when they become unneeded, often because of
an error-condition. The code that does the "real" setjmp should obtain
the stack-mark and the code that gets longjmp'd to should pop the
stack to that point:

	Stack stack;
	static Stack_mark stack_mark;
	static jmp_buf proc_mark;

	...

	if(setjmp(proc_mark) == 0) {
	   stack_mark = Stack_mark_get(&stack);
        }
	else {
	   Stack_pop_to_mark(&stack, stack_mark);
        }
	   



More information about the Comp.lang.c mailing list