Preparing for Obstacks (GNU libiberty)

#### 2.3.1.2 Preparing for Using Obstacks ¶

Each source file in which you plan to use obstacks must include the header file `obstack.h`, like this:

    #include <obstack.h>

Also, if the source file uses the macro `obstack_init`, it must declare or define two macros that will be called by the obstack library. One, `obstack_chunk_alloc`, is used to allocate the chunks of memory into which objects are packed. The other, `obstack_chunk_free`, is used to return chunks when the objects in them are freed. These macros should appear before any use of obstacks in the source file.

Usually these are defined to use `malloc` via the intermediary `xmalloc` (see Unconstrained Allocation in The GNU C Library Reference Manual). This is done with the following pair of macro definitions:

    #define obstack_chunk_alloc xmalloc
    #define obstack_chunk_free free

Though the memory you get using obstacks really comes from `malloc`, using obstacks is faster because `malloc` is called less often, for larger blocks of memory. See Obstack Chunks, for full details.

At run time, before the program can use a `struct obstack` object as an obstack, it must initialize the obstack by calling `obstack_init` or one of its variants, `obstack_begin`, `obstack_specify_allocation`, or `obstack_specify_allocation_with_arg`.

Function: `int` obstack_init `(struct obstack *obstack-ptr)` ¶

  Initialize obstack obstack-ptr for allocation of objects. This macro calls the obstack’s `obstack_chunk_alloc` function. If allocation of memory fails, the function pointed to by `obstack_alloc_failed_handler` is called. The `obstack_init` macro always returns 1 (Compatibility notice: Former versions of obstack returned 0 if allocation failed).

Here are two examples of how to allocate the space for an obstack and initialize it. First, an obstack that is a static variable:

    static struct obstack myobstack;
    ...
    obstack_init (&myobstack);

Second, an obstack that is itself dynamically allocated:

    struct obstack *myobstack_ptr
      = (struct obstack *) xmalloc (sizeof (struct obstack));

    obstack_init (myobstack_ptr);

Function: `int` obstack_begin `(struct obstack *obstack-ptr, size_t chunk_size)` ¶

  Like `obstack_init`, but specify chunks to be at least chunk_size bytes in size.

Function: `int` obstack_specify_allocation `(struct obstack *obstack-ptr, size_t chunk_size, size_t alignment, void *(*chunkfun) (size_t), void (*freefun) (void *))` ¶

  Like `obstack_init`, specifying chunk size, chunk alignment, and memory allocation functions. A chunk_size or alignment of zero results in the default size or alignment respectively being used.

Function: `int` obstack_specify_allocation_with_arg `(struct obstack *obstack-ptr, size_t chunk_size, size_t alignment, void *(*chunkfun) (void *, size_t), void (*freefun) (void *, void *), void *arg)` ¶

  Like `obstack_specify_allocation`, but specifying memory allocation functions that take an extra first argument, arg.

Variable: obstack_alloc_failed_handler ¶

  The value of this variable is a pointer to a function that `obstack` uses when `obstack_chunk_alloc` fails to allocate memory. The default action is to print a message and abort. You should supply a function that either calls `exit` (see Program Termination in The GNU C Library Reference Manual) or `longjmp` and doesn’t return.

      void my_obstack_alloc_failed (void)
      ...
      obstack_alloc_failed_handler = &my_obstack_alloc_failed;