C++ _CrtSetAllocHook-未处理的异常
我使用Windows10x64和VisualStudio2019。下面是一个简单的程序(x86调试),它应该打印内存分配大小:C++ _CrtSetAllocHook-未处理的异常,c++,c,visual-studio,visual-c++,C++,C,Visual Studio,Visual C++,我使用Windows10x64和VisualStudio2019。下面是一个简单的程序(x86调试),它应该打印内存分配大小: #include <iostream> int MyAllocHook(int allocType, void* userData, std::size_t size, int blockType, long requestNumber, const unsigned char* filename, int lineNumber) { std::c
#include <iostream>
int MyAllocHook(int allocType, void* userData, std::size_t size, int blockType, long requestNumber,
const unsigned char* filename, int lineNumber)
{
std::cout << "Alloc: " << size << std::endl;
return 1;
}
int main()
{
_CrtSetAllocHook(MyAllocHook);
void* ptr = malloc(128);
if (ptr)
{
free(ptr);
}
system("pause");
return 0;
}
怎么了?如何解决这个问题?“堆栈溢出”(哈哈)是我的赠品
钩子中的I/O和字符串操作导致了它自己的内存分配,因此钩子会一次又一次地被调用,直到它溢出堆栈
您必须查看blockType
,并明确地从运行时本身排除调用,如下所述:
它以不分配任何内存(这应该是安全的)的方式记录所有非C运行时调用,并在最后报告您的请求生成了明显的预期128字节,再加上处理程序中字符串代码的两个16字节分配:
Alloc : 128
_HOOK_ALLOC _NORMAL_BLOCK Size 128 file (null) line 0 <-- EXPECTED
_HOOK_ALLOC _NORMAL_BLOCK Size 16 file (null) line 0 <-- SURPRISE!
_HOOK_ALLOC _NORMAL_BLOCK Size 16 file (null) line 0 <-- SURPRISE!
_HOOK_FREE _NORMAL_BLOCK Size 0 file (null) line 0
_HOOK_FREE _NORMAL_BLOCK Size 0 file (null) line 0
_HOOK_FREE _NORMAL_BLOCK Size 0 file (null) line 0
Alloc:128
_HOOK_ALLOC_NORMAL_块大小128 file(null)行0“堆栈溢出”(ha-ha)是我的赠品
钩子中的I/O和字符串操作导致了它自己的内存分配,因此钩子会一次又一次地被调用,直到它溢出堆栈
您必须查看blockType
,并明确地从运行时本身排除调用,如下所述:
它以不分配任何内存(这应该是安全的)的方式记录所有非C运行时调用,并在最后报告您的请求生成了明显的预期128字节,再加上处理程序中字符串代码的两个16字节分配:
Alloc : 128
_HOOK_ALLOC _NORMAL_BLOCK Size 128 file (null) line 0 <-- EXPECTED
_HOOK_ALLOC _NORMAL_BLOCK Size 16 file (null) line 0 <-- SURPRISE!
_HOOK_ALLOC _NORMAL_BLOCK Size 16 file (null) line 0 <-- SURPRISE!
_HOOK_FREE _NORMAL_BLOCK Size 0 file (null) line 0
_HOOK_FREE _NORMAL_BLOCK Size 0 file (null) line 0
_HOOK_FREE _NORMAL_BLOCK Size 0 file (null) line 0
Alloc:128
_HOOK_ALLOC_NORMAL_BLOCK Size 128 file(null)行0调用\u CrtSetAllocHook
时,应在回调函数中处理reentrat调用情况。
如果您的myallook
功能代码也试图分配内存,则可能会导致这种情况
一个简单的方法可以是(从以下方面考虑):
static LONG g g_lMallocCalled=0;
int-myAllocook(int-allocType,void*userData,std::size\u t size,int-blockType,long-requestNumber,
常量无符号字符*文件名,整数行号)
{
//防止重传呼叫
如果(InterlockedIncrement(&g_lMallocCalled)>1){//I已被调用
互锁减量(g_lMallocCalled);
返回TRUE;
}
std::cout调用\u CrtSetAllocHook
时,应在回调函数中处理reentrat调用情况。
如果您的myallook
功能代码也试图分配内存,则可能会导致这种情况
一个简单的方法可以是(从以下方面考虑):
static LONG g g_lMallocCalled=0;
int-myAllocook(int-allocType,void*userData,std::size\u t size,int-blockType,long-requestNumber,
常量无符号字符*文件名,整数行号)
{
//防止重传呼叫
如果(InterlockedIncrement(&g_lMallocCalled)>1){//I已被调用
互锁减量(g_lMallocCalled);
返回TRUE;
}
STD::C++使用BythType=O.CRTBY块,但也有很多调用BoSype==正常值块,其中文件名=NULL。如何过滤从我的代码中得到的分配?简短回答:不能在处理程序中执行C++字符串操作和I/O。请参阅我的编辑答案以获得更多信息。锁,但也有很多调用BoSytBy==YangRead块,其中文件名=null。如何过滤从我的代码中得到的分配?简短的答案:你不能在处理程序中做C++字符串操作和I/O。更多信息请参阅我编辑的答案。
#include <iostream>
struct allocinfo {
int size;
const char *filename;
int lineno;
int alloctype;
int blocktype;
};
struct allocinfo allocs[256], *allocp = allocs;
volatile bool capturing = true;
static const char *printableAllocType(int t)
{
switch (t)
{
case _HOOK_ALLOC: return "_HOOK_ALLOC";
case _HOOK_REALLOC: return "_HOOK_REALLOC";
case _HOOK_FREE: return "_HOOK_FREE";
default: return "?";
}
}
static const char *printableBlockType(int t)
{
switch (t)
{
case _FREE_BLOCK: return "_FREE_BLOCK";
case _NORMAL_BLOCK: return "_NORMAL_BLOCK";
case _CRT_BLOCK: return "_CRT_BLOCK";
case _IGNORE_BLOCK: return "_IGNORE_BLOCK";
case _CLIENT_BLOCK: return "_CLIENT_BLOCK";
default: return "?";
}
}
int MyAllocHook( int allocType, void* userData, std::size_t size,
int blockType, long requestNumber,
const unsigned char* filename, int lineNumber)
{
if (blockType == _CRT_BLOCK) return 1;
if (capturing)
{
allocp->size = (int)size;
allocp->lineno = lineNumber;
allocp->blocktype = blockType;
allocp->alloctype = allocType;
allocp->filename = (const char *)filename;
allocp++;
}
static bool firstTime = true;
if (firstTime)
{
firstTime = false;
std::cout << "Alloc : " << size << std::endl;
}
return 1;
}
int main()
{
_CrtSetAllocHook(MyAllocHook);
void* ptr = malloc(128);
if (ptr)
{
free(ptr);
}
capturing = false;
for (struct allocinfo *ap = allocs; ap < allocp; ap++)
printf("%-15s %-15s Size %d file %s line %d\n",
printableAllocType(ap->alloctype),
printableBlockType(ap->blocktype),
ap->size, ap->filename, ap->lineno);
return 0;
}
Alloc : 128
_HOOK_ALLOC _NORMAL_BLOCK Size 128 file (null) line 0 <-- EXPECTED
_HOOK_ALLOC _NORMAL_BLOCK Size 16 file (null) line 0 <-- SURPRISE!
_HOOK_ALLOC _NORMAL_BLOCK Size 16 file (null) line 0 <-- SURPRISE!
_HOOK_FREE _NORMAL_BLOCK Size 0 file (null) line 0
_HOOK_FREE _NORMAL_BLOCK Size 0 file (null) line 0
_HOOK_FREE _NORMAL_BLOCK Size 0 file (null) line 0
static LONG g_lMallocCalled = 0;
int MyAllocHook(int allocType, void* userData, std::size_t size, int blockType, long requestNumber,
const unsigned char* filename, int lineNumber)
{
// Prevent from reentrat calls
if (InterlockedIncrement(&g_lMallocCalled) > 1) { // I was already called
InterlockedDecrement(&g_lMallocCalled);
return TRUE;
}
std::cout << "Alloc: " << size << std::endl;
InterlockedDecrement(&g_lMallocCalled);
return TRUE;
}