Go to the previous, next section.

Memory Allocation

The GNU system provides several methods for allocating memory space under explicit program control. They vary in generality and in efficiency.

Dynamic Memory Allocation Concepts

Dynamic memory allocation is a technique in which programs determine as they are running where to store some information. You need dynamic allocation when the number of memory blocks you need, or how long you continue to need them, depends on the data you are working on.

For example, you may need a block to store a line read from an input file; since there is no limit to how long a line can be, you must allocate the storage dynamically and make it dynamically larger as you read more of the line.

Or, you may need a block for each record or each definition in the input data; since you can't know in advance how many there will be, you must allocate a new block for each record or definition as you read it.

When you use dynamic allocation, the allocation of a block of memory is an action that the program requests explicitly. You call a function or macro when you want to allocate space, and specify the size with an argument. If you want to free the space, you do so by calling another function or macro. You can do these things whenever you want, as often as you want.

Dynamic Allocation and C

The C language supports two kinds of memory allocation through the variables in C programs:

Dynamic allocation is not supported by C variables; there is no storage class "dynamic", and there can never be a C variable whose value is stored in dynamically allocated space. The only way to refer to dynamically allocated space is through a pointer. Because it is less convenient, and because the actual process of dynamic allocation requires more computation time, programmers use dynamic allocation only when neither static nor automatic allocation will serve.

For example, if you want to allocate dynamically some space to hold a struct foobar, you cannot declare a variable of type struct foobar whose contents are the dynamically allocated space. But you can declare a variable of pointer type struct foobar * and assign it the address of the space. Then you can use the operators `*' and `->' on this pointer variable to refer to the contents of the space:

{
  struct foobar *ptr
     = (struct foobar *) malloc (sizeof (struct foobar));
  ptr->name = x;
  ptr->next = current_foobar;
  current_foobar = ptr;
}

Unconstrained Allocation

The most general dynamic allocation facility is malloc. It allows you to allocate blocks of memory of any size at any time, make them bigger or smaller at any time, and free the blocks individually at any time (or never).

Basic Storage Allocation

To allocate a block of memory, call malloc. The prototype for this function is in `stdlib.h'.

Function: void * malloc (size_t size)

This function returns a pointer to a newly allocated block size bytes long, or a null pointer if the block could not be allocated.

The contents of the block are undefined; you must initialize it yourself (or use calloc instead; see section Allocating Cleared Space). Normally you would cast the value as a pointer to the kind of object that you want to store in the block. Here we show an example of doing so, and of initializing the space with zeros using the library function memset (see section Copying and Concatenation):

struct foo *ptr;
...
ptr = (struct foo *) malloc (sizeof (struct foo));
if (ptr == 0) abort ();
memset (ptr, 0, sizeof (struct foo));

You can store the result of malloc into any pointer variable without a cast, because ANSI C automatically converts the type void * to another type of pointer when necessary. But the cast is necessary in contexts other than assignment operators or if you might want your code to run in traditional C.

Remember that when allocating space for a string, the argument to malloc must be one plus the length of the string. This is because a string is terminated with a null character that doesn't count in the "length" of the string but does need space. For example:

char *ptr;
...
ptr = (char *) malloc (length + 1);

See section Representation of Strings, for more information about this.

Examples of malloc

If no more space is available, malloc returns a null pointer. You should check the value of every call to malloc. It is useful to write a subroutine that calls malloc and reports an error if the value is a null pointer, returning only if the value is nonzero. This function is conventionally called xmalloc. Here it is:

void *
xmalloc (size_t size)
{
  register void *value = malloc (size);
  if (value == 0)
    fatal ("virtual memory exhausted");
  return value;
}

Here is a real example of using malloc (by way of xmalloc). The function savestring will copy a sequence of characters into a newly allocated null-terminated string:

char *
savestring (const char *ptr, size_t len)
{
  register char *value = (char *) xmalloc (len + 1);
  memcpy (value, ptr, len);
  value[len] = 0;
  return value;
}

The block that malloc gives you is guaranteed to be aligned so that it can hold any type of data. In the GNU system, the address is always a multiple of eight; if the size of block is 16 or more, then the address is always a multiple of 16. Only rarely is any higher boundary (such as a page boundary) necessary; for those cases, use memalign or valloc (see section Allocating Aligned Memory Blocks).

Note that the memory located after the end of the block is likely to be in use for something else; perhaps a block already allocated by another call to malloc. If you attempt to treat the block as longer than you asked for it to be, you are liable to destroy the data that malloc uses to keep track of its blocks, or you may destroy the contents of another block. If you have already allocated a block and discover you want it to be bigger, use realloc (see section Changing the Size of a Block).

Freeing Memory Allocated with malloc

When you no longer need a block that you got with malloc, use the function free to make the block available to be allocated again. The prototype for this function is in `stdlib.h'.

Function: void free (void *ptr)

The free function deallocates the block of storage pointed at by ptr.

Function: void cfree (void *ptr)

This function does the same thing as free. It's provided for backward compatibility with SunOS; you should use free instead.

Freeing a block alters the contents of the block. Do not expect to find any data (such as a pointer to the next block in a chain of blocks) in the block after freeing it. Copy whatever you need out of the block before freeing it! Here is an example of the proper way to free all the blocks in a chain, and the strings that they point to:

struct chain
  {
    struct chain *next;
    char *name;
  }

void
free_chain (struct chain *chain)
{
  while (chain != 0)
    {
      struct chain *next = chain->next;
      free (chain->name);
      free (chain);
      chain = next;
    }
}

Occasionally, free can actually return memory to the operating system and make the process smaller. Usually, all it can do is allow a later later call to malloc to reuse the space. In the mean time, the space remains in your program as part of a free-list used internally by malloc.

There is no point in freeing blocks at the end of a program, because all of the program's space is given back to the system when the process terminates.

Changing the Size of a Block

Often you do not know for certain how big a block you will ultimately need at the time you must begin to use the block. For example, the block might be a buffer that you use to hold a line being read from a file; no matter how long you make the buffer initially, you may encounter a line that is longer.

You can make the block longer by calling realloc. This function is declared in `stdlib.h'.

Function: void * realloc (void *ptr, size_t <