分配挂钩和 C 运行时内存分配
对分配挂钩函数的一个非常重要的限制是,当它们调用任何分配内部内存的 C 运行库函数时,必须显式忽略 _CRT_BLOCK 块(由 C 运行库函数内部进行的内存分配)。可通过在分配挂钩函数起始包括如下代码来忽略 _CRT_BLOCK 块:
if ( nBlockUse == _CRT_BLOCK )
return( TRUE );
如果您的分配挂钩未忽略 _CRT_BLOCK 块,那么挂钩中调用的任何 C 运行库函数都会使程序陷入无穷循环。例如,printf 执行内部分配。如果挂钩代码调用 printf,那么产生的分配将导致再次调用挂钩,而挂钩又再次调用 printf,如此继续直到堆栈溢出。如果需要报告 _CRT_BLOCK 分配操作,回避该限制的一种方法是,使用 Windows API 函数而不是 C 运行时函数来进行格式化和输出。因为 Windows API 不使用 C 运行库堆,所以它们不会使您的分配挂钩陷入无穷循环。
如果检查运行库源文件,将看到默认分配挂钩函数 CrtDefaultAllocHook(只返回 TRUE)位于其自己的单独文件 DBGHOOK.C 中。如果希望甚至为运行时启动代码(在您应用程序的 main 函数之前执行)进行的分配调用您的分配挂钩,可以用您自己的函数替换此默认函数,而不使用 _CrtSetAllocHook。