next up previous contents
Next: Data Representation Up: Pointers and Malloc Previous: Dynamic Memory Allocation

Dynamically Allocating Arrays

One-Dimensional Arrays

In C, arrays must have their extents defined at compile-time. There's no way to postpone the definition of the size of an array until runtime. Luckily, with pointers and malloc, we can work around this limitation.

To allocate a one-dimensional array of length N of some particular type, simply use malloc to allocate enough memory to hold N elements of the particular type, and then use the resulting pointer as if it were an array. For example, the following code snippet allocates a block of N ints, and then, using array notation, fills it with the values 0 through N-1:

        int *A = malloc (sizeof (int) * N);
        int i;

        for (i = 0; i < N; i++)
            A[i] = i;

Pictorially, the ``array'' A might be drawn as:

This idea is very useful for dealing with strings, which in C are represented by arrays of chars, terminated with a '\0' character. These arrays are nearly always expressed as pointers in the declaration of functions, but accessed via C's array notation. For example, here is a function that implements strlen:

        int strlen (char *s)
        {
            int i;

            for (i = 0; s[i] != '\0'; i++)
                ;

            return (i)
        }

Two-Dimensional Arrays

Unfortunately, the convenient relationship between pointers and arrays in C breaks down for arrays of higher dimension. Luckily, we can treat two-dimensional arrays as arrays of one-dimensional arrays. An illustration of this is shown in figure B.3, and code to allocate such an array is shown in figure B.4.

 
Figure B.3:   A Two-Dimensional Dynamically Allocated Array

 
Figure B.4:   Code to create an array.

A Digression Into Engineering

From the perspective of software engineering, the code in figure B.4 has serious flaws. First, it doesn't do any error checking- it doesn't check to make sure that the number of rows and columns requested are sensible, and it doesn't check any of the values returned from malloc to make sure that they are not NULL. Next, the array returned is filled with undefined values- whatever values happened to be in the memory that malloc allocated for you are now the contents of this array. Finally, the array itself carries around no information about what its extents are (how many rows and columns it has). This information may be represented elsewhere in the program, but general software engineering guidelines recommend that this information be kept with the array.

Figure B.5 shows a more realistic approach, which defines a new type named array2d_t to represent a dynamically allocated 2-d array, and a function to create arrays and fill them with a specific initial value.

 
Figure B.5:   Better code to allocate a 2-d array.

An illustration of the result of this code, again for allocating a 3-by-8 array, is shown in figure B.6.

 
Figure:   An array2d_t array.


next up previous contents
Next: Data Representation Up: Pointers and Malloc Previous: Dynamic Memory Allocation

Dan Ellard
Mon Jul 21 22:30:59 EDT 1997