メインコンテンツ

範囲外の配列インデックス

配列が範囲外にアクセスする

説明

配列要素へのアクセスに関するこのチェックでは、要素が配列の範囲外かどうかを判別します。チェックは、インデックス表記を使用して配列要素を読み取ったときにのみ発生し、配列要素のアドレスを取得したときには発生しません。

すべて展開する

#include <stdio.h>

void fibonacci(void)
{
  int i;
  int fib[10];
 
  for (i = 0; i < 10; i++) 
  {
    if (i < 2) 
      fib[i] = 1;
    else 
      fib[i] = fib[i-1] + fib[i-2];
    }

  printf("The 10-th Fibonacci number is %i .\n", fib[i]);   
}

int main(void) {
  fibonacci();
}

この例では、配列 fib にはサイズ 10 が割り当てられています。fib の配列インデックスに許可される値は [0,1,2,...,9] です。変数 ifor ループから出るときの値は 10 です。したがって、printf ステートメントが i を通して fib[10] へのアクセスを試みると、[範囲外の配列インデックス] チェックはレッド エラーを生成します。

このチェックはまた、printffib[i] ではなく *(fib+i) を使用する場合にもレッド エラーを生成します。

修正 — 配列インデックスを配列のサイズより小さく維持

1 つの修正方法として、for ループの後で、fib[i] ではなく fib[i-1] を出力するとします。

#include <stdio.h>

void fibonacci(void)
{
  int i;
  int fib[10];
 
  for (i = 0; i < 10; i++) 
  {
    if (i < 2) 
      fib[i] = 1;
    else 
      fib[i] = fib[i-1] + fib[i-2];
    }

  printf("The 10-th Fibonacci number is %i .\n", fib[i-1]);   
}

int main(void) {
  fibonacci();
}
extern int arr[];

int getFifthElement(void) {
   return arr[5];
}
int main(void){
	getFifthElement();
}

Code Prover は、既定で、サイズが未定義の外部配列は任意のインデックスで安全にアクセスできると仮定します。外部配列アクセスに対する [範囲外の配列インデックス] チェックはグリーンです。

この既定の仮定を除外するには、オプション [安全でない外部配列アクセスを検討する] (-consider-external-array-access-unsafe) を使用します。このオプションを使用すると、[範囲外の配列インデックス] チェックがオレンジになります。

extern int arr[];

int getFifthElement(void) {
   return arr[5];
}
int arr[10];

int main(int arg, char* argv[]) {
    int *ptr = &arr[10];
    int val_ptr = *ptr;
    return 0;
}

この例では、ポインター ptr に、配列 arr に割り当てられているメモリを超えたアドレスが代入されています。ただし、この代入によって [範囲外の配列インデックス] チェックはトリガーされません。代わりに、そのポインターがデリファレンスされた場合にのみ [不適切にデリファレンスされたポインター] チェックが行われ、このチェックは明確なエラー (レッド) を示します。

チェック情報

グループ: 静的メモリ
言語: C | C++
頭字語: OBAI

バージョン履歴

すべて展開する