|
|||
Department of Engineering | |
University of Cambridge > Engineering Department > computing help |
#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].