[Univ of Cambridge] [Dept of Engineering]
next up previous contents
Next: Signals and error handling Up: More on Arrays, Pointers Previous: Multidimensional Arrays

realloc

Suppose we have a simple array, and a subfunction for adding items to it:
#define MAXELTS 100

int array[MAXELTS];
int num_of_elements = 0;

install(int x)
{
   if(num_of_elements >= MAXELTS){
      fprintf(stderr, "too many elements (max %d)\n", MAXELTS);
      exit(1);
   }
   array[num_of_elements++] = x;
}
Let's see how easy it is to remove the arbitrary limitation in this code, by dynamically re-allocating the array:
#include <stdlib.h>

int *array = NULL;
int nalloc = 0;
int num_of_elements = 0;

install(x)
int x;
{
  if(num_of_elements >= nalloc){
  /* We're out of space. Reallocate with space for 10 more ints */ 
    nalloc += 10;
    array = (int *)realloc((char *)array, nalloc * sizeof(int));
    if(array == NULL){
       fprintf(stderr, "out of memory with %d elements\n", 
                        num_of_elements);
       exit(1);
    }
  }

  array[num_of_elements++] = x;
}
If you want to be true-blue ANSI, use size_t for nalloc and num_of_elements.

When dynamically allocating a multidimensional array, it is usually best to allocate an array of pointers, and then initialize each pointer to a dynamically-allocated ``row''. The resulting ``ragged" array can save space, although it is not necessarily contiguous in memory as a real array would be. Here is a two-dimensional example:

     /* create an array of pointers */
     int **array = (int **)malloc(nrows * sizeof(int *));
     if (array == NULL){
        fprintf(stderr,"Out of memory\n");
        exit(1);
     }
        
     for(i = 0; i < nrows; i++){
         /* create space for an array of ints */
         array[i] = (int *)malloc(ncolumns * sizeof(int));
           if (array[i] == NULL){
               fprintf(stderr,"Out of memory\n");
               exit(1);
           }
     }
You can keep the array's contents contiguous, while making later reallocation of individual rows difficult, with a bit of explicit pointer arithmetic:
     int **array = (int **)malloc(nrows * sizeof(int *));
     if (array == NULL){
        fprintf(stderr,"Out of memory\n");
        exit(1);
     }

     array[0] = (int *)malloc(nrows * ncolumns * sizeof(int));
     if (array[0] == NULL){
        fprintf(stderr,"Out of memory\n");
        exit(1);
     }

     for(i = 1; i < nrows; i++)
        array[i] = array[0] + i * ncolumns;
In either case, the elements of the dynamic array can be accessed with normal-looking array subscripts: array[i][j].

If the double indirection implied by the above schemes is for some reason unacceptable, you can simulate a two-dimensional array with a single, dynamically-allocated one-dimensional array:

     int *array = (int *)malloc(nrows * ncolumns * sizeof(int));
However, you must now perform subscript calculations manually, accessing the i,j th element with array[i * ncolumns + j].


next up previous contents
Next: Signals and error handling Up: More on Arrays, Pointers Previous: Multidimensional Arrays
Tim Love
1999-10-06