Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ _CrtSetAllocHook-未处理的异常_C++_C_Visual Studio_Visual C++ - Fatal编程技术网

C++ _CrtSetAllocHook-未处理的异常

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

我使用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::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;
}