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

イネーブルモジュールと非イネーブルモジュールの使用

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

イネーブルモジュールはポインターチェッカーのコンパイルオプションを有効にしてコンパイルしたモジュールで、非イネーブルモジュールはこのコンパイラー・オプションを無効にしてコンパイルしたモジュールです。

メモリーへのポインターを記述するか、非イネーブルモジュールからポインターを返すと、ポインターに不正な範囲情報が含まれることがあります。イネーブルモジュールで不正な範囲情報を含むポインターを使用すると、範囲がポインターに対応していないため、ポインターチェッカーは誤った範囲外エラーをレポートします。

この問題を最小限に抑えるため、ポインターチェッカーはポインターのコピーを範囲情報とともに格納します。ポインターがメモリーにロードされると、ポインターの値がポインターコピーの値と比較されます。これらの 2 つの値が一致すると、範囲情報は正しいと見なされ、この範囲情報が使用されます。しかし、2 つの値が一致しない場合、任意のメモリーへのアクセスを許可するように範囲が設定されます。

非イネーブルモジュールからのポインターが範囲情報を含むポインターコピーと一致していれば、この場合でもポインターチェッカーは範囲外エラーをレポートできます。

例えば、非イネーブルモジュールからのランタイム・ライブラリー関数を使用して次のポインターを作成する場合を考えます。

RTL 関数により作成されたポインターの例

p = my_realloc(p, old_size + 100);

メモリー・アロケーターが p に割り当てられたメモリーを単純に拡張でき、同じポインターを返す場合、イネーブルモジュールはこのポインターと古い範囲情報を使用できます。 ポインターチェッカーは realloc() 関数によって作成された拡張のことを知らないため、範囲外エラーをレポートします。

イネーブルモジュールと非イネーブルモジュールを利用しているときに誤った範囲外エラーがレポートされることを防ぐには、次のいずれかの操作を行います。

範囲情報の削除

範囲情報を削除すると、このポインターのポインターチェックは無効になります。__chkp_kill_bounds() 組込み関数を使用して範囲情報を削除できます。

__chkp_kill_bounds() により範囲情報を削除する例

void * unknown_pointer_returning_function() {
   ... 
   // リターンポインターに組込み関数を使用
   return __chkp_kill_bounds(the_ptr);
}

正しい範囲情報の設定

__chkp_make_bounds() 組込み関数を使用して、ポインターの正しい範囲情報を設定できます。

例えば、Windows® の HeapAlloc() 関数を使用してポインターを作成します。 このオペレーティング・システム関数は非イネーブルモジュールからのものであるため、この関数からのポインターには正しい範囲情報は含まれません。

正しい範囲情報を含むポインターを取得するには、戻り値に __chkp_make_bounds() 組込み関数を使用します。

__chkp_make_bounds() を使用してポインターを取得する例

void * myalloc(size_t size){ return __chkp_make_bounds(HeapAlloc(MyHeap, flags, size), size); }