インテル® C++ コンパイラー XE 13.1 ユーザー・リファレンス・ガイド
イネーブルモジュールはポインターチェッカーのコンパイルオプションを有効にしてコンパイルしたモジュールで、非イネーブルモジュールはこのコンパイラー・オプションを無効にしてコンパイルしたモジュールです。
メモリーへのポインターを記述するか、非イネーブルモジュールからポインターを返すと、ポインターに不正な範囲情報が含まれることがあります。イネーブルモジュールで不正な範囲情報を含むポインターを使用すると、範囲がポインターに対応していないため、ポインターチェッカーは誤った範囲外エラーをレポートします。
この問題を最小限に抑えるため、ポインターチェッカーはポインターのコピーを範囲情報とともに格納します。ポインターがメモリーにロードされると、ポインターの値がポインターコピーの値と比較されます。これらの 2 つの値が一致すると、範囲情報は正しいと見なされ、この範囲情報が使用されます。しかし、2 つの値が一致しない場合、任意のメモリーへのアクセスを許可するように範囲が設定されます。
非イネーブルモジュールからのポインターが範囲情報を含むポインターコピーと一致していれば、この場合でもポインターチェッカーは範囲外エラーをレポートできます。
例えば、非イネーブルモジュールからのランタイム・ライブラリー関数を使用して次のポインターを作成する場合を考えます。
p = my_realloc(p, old_size + 100);
メモリー・アロケーターが p に割り当てられたメモリーを単純に拡張でき、同じポインターを返す場合、イネーブルモジュールはこのポインターと古い範囲情報を使用できます。 ポインターチェッカーは realloc() 関数によって作成された拡張のことを知らないため、範囲外エラーをレポートします。
イネーブルモジュールと非イネーブルモジュールを利用しているときに誤った範囲外エラーがレポートされることを防ぐには、次のいずれかの操作を行います。
__chkp_kill_bounds() 組込み関数を使用してポインターから範囲情報を削除します。
イネーブルモジュールで __chkp_make_bounds() 組込み関数を使用して正しい範囲情報を設定します。
範囲情報を削除すると、このポインターのポインターチェックは無効になります。
例えば、__chkp_kill_bounds() 組込み関数を使用して範囲情報を削除できます。
void * unknown_pointer_returning_function() { // コード // リターンポインターに組込み関数を使用 return __chkp_kill_bounds(the_ptr); }
例えば、Windows* の HeapAlloc() 関数を使用してポインターを作成します。 このオペレーティング・システム関数は非イネーブルモジュールからのものであるため、この関数からのポインターには正しい範囲情報は含まれません。
正しい範囲情報を含むポインターを取得するには、戻り値に __chkp_make_bounds() 組込み関数を使用します。
void * myalloc(size_t size) { return __chkp_make_bounds(HeapAlloc(MyHeap, flags, size), size); }