割り当てフック関数と C ランタイムのメモリ割り当て

メモリ割り当て用のフック関数には重要な制限事項があります。それは、メモリを内部的に割り当てるタイプの C ランタイム ライブラリ関数をフック関数から呼び出す場合、_CRT_BLOCK 型のブロック (C ランタイム ライブラリ関数によって内部的に割り当てられるメモリ) を明示的に無視する必要があることです。 割り当て用のフック関数の先頭に次のようなコードを追加すると、_CRT_BLOCK 型のブロックを無視できます。

    if ( nBlockUse == _CRT_BLOCK )
        return( TRUE );

割り当て用のフック関数で _CRT_BLOCK 型のブロックを無視しないと、このフック関数から C ランタイム ライブラリ関数を呼び出した場合に、プログラムが無限ループに陥ることがあります。 たとえば、printf は内部的にメモリを割り当てます。 このため、フック関数の中で printf を呼び出すと、その結果行われるメモリ割り当てによって再びフック関数が呼び出され、それによって再び printf が呼び出されるという繰り返しが発生し、結果的にスタック オーバーフローが発生してしまいます。 _CRT_BLOCK 型の割り当て処理をレポートする必要がある場合は、この制限事項を回避するために、C ランタイム関数ではなく Windows API 関数を使用して書式設定や出力を行う方法があります。 Windows API は C ランタイム ライブラリのヒープを使用しないため、割り当て用のフック関数を使用しても無限ループに陥る心配はありません。

ランタイム ライブラリのソース ファイルの DBGHOOK.C の中に、既定の割り当て用のフック関数 CrtDefaultAllocHook があります。この関数は単に TRUE を返します。 アプリケーションの main 関数の前に実行されるランタイムのスタートアップ コードによるメモリ割り当て時にもフック関数が呼び出されるようにするには、_CrtSetAllocHook を使用する代わりに、この既定のフック関数を独自の関数に置き換えます。

参照

その他の技術情報

デバッグ用フック関数の作成

crt_dbg2 Sample