警告 C6200

インデックス 'index' が、非スタック バッファー 'parameter-name' の有効なインデックス範囲 'min' から 'max' の範囲外です

この警告は、指定された非スタック配列への整数オフセットがその配列の最大境界を超え、未定義の動作が発生し、クラッシュする可能性があることを示します。

解説

この欠陥の一般的な原因の 1 つは、配列のサイズを、配列へのインデックスとして使用していることです。 C/C++ の配列インデックスは 0 から始まるため、配列への有効な最大インデックスは、配列要素の数より 1 つ少なくなります。

コード分析名: INDEX_EXCEEDS_MAX_NONSTACK

この警告が発生するコード例を次に示します。 この問題は、インデックス 13 (14 番目の要素) が最後の場合にインデックス 14 (15 番目の要素) にアクセスしようとする、インデックス範囲を超えるループに起因 for します。

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;
}

両方の警告を修正するには、次のコードに示すように、正しい配列サイズを使用します。

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;
}

ヒューリスティック

コード分析では、配列インデックスが範囲内にあるかどうかを常に証明できるわけではありません。 これは、たとえば、他の関数を呼び出す式を含む複雑な式からインデックスが計算されるときに発生する可能性があります。 このような場合、コード分析は他の手掛かりにフォールバックして、配列インデックス式が分類される範囲を決定する可能性があります。

たとえば、コード分析では分析できない関数呼び出しのスタンドインとしてインデックス計算で使用 rand() する次の関数を考えてみましょう。

#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;
}

コード分析は、戻り値に関する情報がないため、 rand() 警告を表示しません。 一方、戻り値rand()の範囲に関するヒントを提供しrand() % 14rand() % 15コード分析はその情報を使用して、インデックスが最初のケースでは範囲外であり、2 番目のケースでは範囲外であることを判断できます。