_CrtSetAllocHookでメモリアロケーション検知

VC++にはメモリアロケーションをフックするために、_CrtSetAllocHookという関数が用意されています。

今回はこれを利用してみたいと思います。

ちなみに_DEBUGマクロが定義されていないと動作しません。

Hook関数

アローケーション時にprintfする関数を定義してみます。

blockTypeが_CRT_BLOCKの時はCランタイムライブラリによって呼び出されたものなので無視します。(そうしないとprintfでクラッシュします。)

allocTypeが_HOOK_ALLOCの時にprintfします。

返り値をTRUEにすることで、既定のアロケーションを呼び出すようにします。(FALSEだとアロケーションが行われません。)

int Hook(
    int allocType,
    void *userData,
    size_t size,
    int blockType,
    long requestNumber,
    const unsigned char *filename,
    int lineNumber
) {
    if (blockType == _CRT_BLOCK) {
        return TRUE;
    }
    if (allocType == _HOOK_ALLOC) {
        printf("alloc\n");
    }
    return TRUE;
}


動作確認

下記の様に記述すると、newの行でallocと出力されます。

_CrtSetAllocHook(Hook);
int* p = new int(10); // alloc

ちなみに、std::functionにラムダを代入する際はキャプチャの大きさによってアロケーションが行われたり行われなかったりするのですが、それを確認できたりします。

_CrtSetAllocHook(Hook);

int x1;
std::function<void()> f1 = [x1] {};

int x2[10];
std::function<void()> f2 = [x2] {}; // alloc

Hookを解除する場合はNULLを設定します。

_CrtSetAllocHook(NULL);