インテル® 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] なのでここで範囲外エラーが発生 |