Previous Page
Next Page

8.1. Defining Arrays

The definition of an array determines its name, the type of its elements, and the number of elements in the array. An array definition without any explicit initialization has the following syntax:

type name[ number_of_elements ];

The number of elements, between square brackets ([ ]), must be an integer expression whose value is greater than zero. An example:

char buffer[4*512];

This line defines an array with the name buffer, which consists of 2,048 elements of type char.

You can determine the size of the memory block that an array occupies using the sizeof operator. The array's size in memory is always equal to the size of one element times the number of elements in the array. Thus, for the array buffer in our example, the expression sizeof(buffer) yields the value of 2048 * sizeof(char); in other words, the array buffer occupies 2,048 bytes of memory, because sizeof(char) always equals one.

In an array definition, you can specify the number of elements as a constant expression, or, under certain conditions, as an expression involving variables. The resulting array is accordingly called a fixed-length or a variable-length array.

8.1.1. Fixed-Length Arrays

Most array definitions specify the number of array elements as a constant expression. An array so defined has a fixed length. Thus the array buffer defined in the previous example is a fixed-length array.

Fixed-length arrays can have any storage class: you can define them outside all functions or within a block, and with or without the storage class specifier static. The only restriction is that no function parameter can be an array. An array argument passed to a function is always converted into a pointer to the first array element (see the section "Arrays as Function Parameters" in Chapter 7).

The four array definitions in the following example are all valid:

int a[10];             // a has external linkage.
static int b[10];      // b has static storage duration and file scope.

void func( )
  static int c[10];    // c has static storage duration and block scope.
  int d[10];           // d has automatic storage duration.
  /* ... */

8.1.2. Variable-Length Arrays

C99 also allows you to define an array using a nonconstant expression for the number of elements, if the array has automatic storage durationin other words, if the definition occurs within a block and does not have the specifier static. Such an array is then called a variable-length array.

Furthermore, the name of a variable-length array must be an ordinary identifier (see the section "Identifier Name Spaces" in Chapter 1). Thus members of structures or unions cannot be variable-length arrays . In the following examples, only the definition of the array vla is a permissible definition:

void func( int n )
  int vla[2*n];             // OK: storage duration is automatic.
  static int e[n];          // Illegal: a variable length array cannot have
                            //          static storage duration.
  struct S { int f[n]; };   // Illegal: f is not an ordinary identifier.
  /* ... */

Like any other automatic variable, a variable-length array is created anew each time the program flow enters the block containing its definition. As a result, the array can have a different length at each such instantiation. Once created, however, even a variable-length array cannot change its length during its storage duration.

Storage for automatic objects is allocated on the stack, and is released when the program flow leaves the block. For this reason, variable-length array definitions are useful only for small, temporary arrays. To create larger arrays dynamically, you should generally allocate storage space explicitly using the standard functions malloc( ) and calloc( ). The storage duration of such arrays then ends with the end of the program, or when you release the allocated memory by calling the function free( ) (see Chapter 12).

Previous Page
Next Page