Condividi tramite


Avviso C6200

L'indice 'index' non è compreso nell'intervallo di indici valido 'min' a 'max' per il buffer nonstack 'parameter-name'

Questo avviso indica che un offset integer nella matrice nonstack specificata supera i limiti massimi di tale matrice, causando un comportamento non definito e potenzialmente si arresta in modo anomalo.

Osservazioni:

Una causa comune di questo difetto consiste nell'usare le dimensioni di una matrice come indice nella matrice. Poiché l'indicizzazione di matrici C/C++ è in base zero, l'indice legale massimo in una matrice è minore del numero di elementi della matrice.

Nome dell'analisi del codice: INDEX_EXCEEDS_MAX_NONSTACK

Esempio

Il codice seguente genera questo avviso. Questo problema deriva dal for ciclo che supera l'intervallo di indici, tentando di accedere all'indice 14 (il 15° elemento) quando l'indice 13 (il 14° elemento) è l'ultimo:

void f()
{
    int* buff = new int[14]; // array of 0..13 elements
    for (int i = 0; i <= 14; i++) // i exceeds the index
    {
        buff[i] = 0; // warning C6200
    }
    delete[] buff;
}

Per correggere entrambi gli avvisi, usare le dimensioni corrette della matrice, come illustrato nel codice seguente:

void f()
{
    int* buff = new int[14]; // array of 0..13 elements
    for (int i = 0; i < 14; i++) // i == 13 on the final iteration
    {
        buff[i] = 0; // initialize buffer
    }
    delete[] buff;
}

Euristica

L'analisi del codice non è sempre in grado di dimostrare se un indice di matrice è compreso nell'intervallo. Ciò può verificarsi, ad esempio, quando l'indice viene calcolato da un'espressione complessa, incluse quelle che chiamano in altre funzioni. In questi casi, l'analisi del codice può eseguire il fallback su altri indizi per determinare l'intervallo in cui può rientrare un'espressione di indice di matrice.

Si consideri ad esempio la funzione seguente che usa rand() nei calcoli dell'indice come stand-in per una chiamata di funzione che l'analisi del codice non può analizzare:

#include <stdlib.h>

void f()
{
    int* buff = new int[14];
    for (int i = 1; i < 14; i++)
    {
        buff[rand()] = 0;       // no warning, nothing is known about the return value of rand()
        buff[rand() % 15] = 0;  // warning C6200, rand() % 15 is known to be in the range 0..14 and index 14 is out of bounds
        buff[rand() % 14] = 0;  // no warning, rand() % 14 is known to be in the range 0..13
    }
    delete[] buff;
}

L'analisi del codice non avvisa solo rand() perché non contiene informazioni sul valore restituito. D'altra parte, rand() % 15 e rand() % 14 fornire hint per l'intervallo del valore restituito di rand() e l'analisi del codice può usare tali informazioni per determinare che l'indice non è compreso nei limiti nel primo caso, ma non nel secondo.