インテル® C++ コンパイラー 18.0 デベロッパー・ガイドおよびリファレンス

範囲のチェック

ポインターチェッカーは、macOS* システムではサポートされていません。

ポインターチェッカーは範囲外のアクセスがないかポインターによる間接アクセスをチェックします。

読み取り/書き込み操作の範囲のチェック

ポインターの範囲をチェックするには、rw 引数を指定して [Q]check-pointers コンパイラー・オプションを使用し、モジュールをコンパイルします。

write 引数を指定してポインターの範囲をチェックすることもできます。この場合は、書き込み操作のポインターの範囲のみチェックされます。

malloc() 関数を使用して要素数 10 の配列を作成し、各配列要素に文字を書き込むケースについて考えます。

各配列要素へ書き込む例

char *buf = malloc(10);
for (int i=0; i<=10; i++) { buf[i] = 'A' + i; }

配列の要素数は 10 ですが、ループは 11 回繰り返されています。11 回目の繰り返しで、関数は割り当てられたメモリーの外部にある配列の 11 番目の要素に文字を書き込みます。範囲のチェック対象が読み取り/書き込み操作か、書き込み操作のみかにかかわらず、ポインターチェッカーは範囲外エラーをレポートします。静的に割り当てられたバッファーの場合でも、ポインターチェッカーはエラーをレポートします。次のコードについて考えてみます。

静的に割り当てられたバッファーでの範囲外エラーの例

fprintf(stderr, "buf[%d]=%d\n",i,buf[i]);

buf[i] への参照は読み取り (ロード) 操作です。そのため、範囲のチェック対象を書き込み操作のみにした場合、範囲外エラーはレポートされません。

ポインター計算とポインターチェック

ポインター計算はポインターチェッカーに影響しません。ポインターが範囲外のアドレスを間接参照しない限り、ポインターは範囲外になり得ます。

要素数 100 の配列を作成する場合、次の条件が適用されます。

ポインター計算とポインターチェックの例

char *p = malloc(100);
  p += 200;	   // ポインターは範囲外だがエラーなし
  p[-101] = 0; // 元は p[99] なのでアクセスはまだ範囲内
  p[0] = 0;    // 元は p[200] なのでここで範囲外エラーが発生

関連情報