# V557. Possible array overrun.

The analyzer detected a potential memory access outside an array. The most common case is an error occurring when writing the '\0' character after the last array's item.

Let's examine a sample of this error:

    struct IT_SAMPLE
    {
      unsigned char filename[14];
      ...
    };

    static int it_riff_dsmf_process_sample(
      IT_SAMPLE * sample, const unsigned char * data)
    {
      memcpy( sample->filename, data, 13 );
      sample->filename[ 14 ] = 0;
      ...
    }

The last array's item has index 13, not 14. That is why the correct code is this one:

    sample->filename[13] = 0;

Of course, you'd better use an expression involving the sizeof() operator instead of constant index' value in such cases. However, remember that you may make a mistake in this case too. For example:

    typedef wchar_t letter;
    letter    name[30];
    ...
    name[sizeof(name) - 1] = L'\0';

At first sight, the "sizeof(name) - 1" expression is right. But the programmer forgot that he handled the 'wchar_t' type and not 'char'. As a result, the '\0' character is written far outside the array's boundaries. This is the correct code:

    name[sizeof(name) / sizeof(*name) - 1] = L'\0';

To simplify writing of such constructs, you may use this special macro:

    #define str_len(arg) ((sizeof(arg) / sizeof(arg[0])) - 1)
    name[str_len(name)] = L'\0';

The analyzer detects some errors when the index is represented by a variable whose value might run out of the array's boundaries. For example:

    int buff[25];
    for (int i=0; i <= 25; i++)
      buff[i] = 10;

This is the correct code:

    int buff[25];
    for (int i=0; i < 25; i++)
      buff[i] = 10;

Note that the analyzer might make mistakes when handling such value ranges and generate false alarms.

This diagnostic is classified as:

CWE-119 CWE-125 CWE-787 CERT-ARR30-C

You can look at examples of errors detected by the V557 diagnostic.