Previous: 7.6 Arrays for Databases
Up: 7 Arrays
Next: 7.8 Summary
Previous Page: 7.6 Arrays for Databases
Next Page: 7.8 Summary

7.7 Common Errors

  1. Array index exceeds the array size. For example, consider the following code for bubble sort:

    for (i = 0; i < MAX; i++)
              for (j = 0; j < MAX; j++)
                   if (a[j] > a[j + 1])
                        ...

    When j is MAX - 1, a[j+1] is outside the array. Make sure array index is inside the actual array.

  2. Use of an array name as an Lvalue: An array name has a fixed value of the address where the array is allocated. It is NOT a variable; it cannot be used as an Lvalue and assigned a new value. Here are some example:

    1. int x[10];
      

      while (*x) { ... x++; /* ERROR */ }

      x cannot be used as an Lvalue and assigned new values.

    2. char msg[80];
      ...
      while (*msg) {
          ...
          msg++;    /* ERROR */
      }

      msg cannot be used as an Lvalue.

    3. char msg[80];
      

      msg = "This is a message"; /* ERROR */

      msg cannot be an Lvalue. The right hand side is not a problem. Value of a string constant is a pointer to an array automatically allocated by the compiler.

    4. char msg[80] = "This is a message";
      

      /* OK: array initialized to the string when memory is allocated */

      A string constant initializer is correct. When memory is allocated for the array, it is initialized to the string constant specified.

  3. Failure to define an array: Definition of an array is required to allocate memory for storage of an array of objects. A pointer type allocates memory for a pointer variable, NOT for an array of objects. Suppose, read_str() reads a string and stores it where its argument points:

    int *pmsg;    /* memory allocated for a pointer variable */
    

    read_str(pmsg); /* ERROR: memory not allocated for a string */

    No memory is allocated for a string, i.e. an array of characters. The variable, pmsg points to some garbage address; read_str() will attempt to store the string at that garbage address. The address may be invalid, in which case there will be a memory fault; a fatal error. Allocate memory for a string with an array declaration:

    int str[MAX];
    read_str(str);

  4. Array pointer not passed to a called function: If a called function is to store values in an array for later use by the calling function, it should be passed a pointer to an array defined in the calling function. Here is a program with an error.
    #include <stdio.h>
    main()
    {   char * p, s[80],
             * get_word(char * s);
    

    p = get_word(s); /* ERROR: returned pointer points to freed memory */ puts(p); /* Prints garbage */ }

    char * get_word(char *str) { char wd[30]; /* memory allocated for array wd[] */ int i = 0; while (*str == ' ') /* skip leading blanks */ ; while (*str != ' ') /* while not a delimiter */ wd[i++] = *str++; /* copy char into array wd[] */ wd[i] = '\0'; /* append a NULL to string in wd[] */ return wd; /* return pointer to wd[] */ } /* memory for array wd[] is freed */

    The function, get_word() copies a word from a string, s, into an automatic array, wd[] for which memory is allocated in get_word(). When get_word() returns, a pointer, wd, to the calling function, the memory allocated for wd[] is freed for other uses, since it was allocated only for get_word(). The data stored in wd[] may be overwritten with other data. In the calling function, p is assigned an address value which points to freed memory. The function, puts(), will print a garbage sequence of characters pointed to by p. At times, the memory may not be reused right away and it will print the correct string. At other times, it will print out garbage.

  5. Errors in passing array arguments: Only array names, i.e., pointers to arrays, should be passed as arguments. The following are all in ERROR:
    func(s[]);
        func(s[80]);
        func(*s);
    Pointers to arrays, i.e. array names by themselves, should be passed as arguments in function calls. Arguments in the above function calls are not pointers. The first one is meaningless in an expression; the second attempts to pass an element at index 80; the third passes a dereferenced pointer, not the pointer to the array.

  6. Errors in declaring formal parameters: Formal parameters referencing arrays in function definitions should be specified to be pointers, not objects of a base type. Consider a function, init(), that initializes elements of an integer array to some values. The following is an error:
    init(int aray)
        {
             ...
        }
    The parameter declared is an integer not a pointer to an integer. It should be either of the following:
    init(int * aray)
    OR
    init(int aray[])
    In either of the above cases, memory for an integer pointer is allocated, NOT for a new array of integers.

  7. Misinterpreting formal parameter declarations: Even if an array size is specified in a formal parameter, memory is not allocated for an array but for a pointer.
    init(int aray[10])
    The above declares aray as an integer pointer.
  8. Pointers are not initialized:
    int x, * px;
         x = 10;
         printf("*px = %d\n", *px);
    Since value of px is garbage, there will be a fatal memory fault when an attempt is made to evaluate *px.



Previous: 7.6 Arrays for Databases
Up: 7 Arrays
Next: 7.8 Summary
Previous Page: 7.6 Arrays for Databases
Next Page: 7.8 Summary

tep@wiliki.eng.hawaii.edu
Wed Aug 17 08:56:22 HST 1994