Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/134.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++ 我可以切换Visual C++;运行时到另一堆?_C++_Visual C++_Memory Management - Fatal编程技术网

C++ 我可以切换Visual C++;运行时到另一堆?

C++ 我可以切换Visual C++;运行时到另一堆?,c++,visual-c++,memory-management,C++,Visual C++,Memory Management,我的程序使用了一个第三方动态链接库,里面有巨大的内存泄漏。我的程序和库都是VisualC++原生代码。两者都动态链接到VisualC++运行时。 < >我想将库强制另一堆,以便在库代码运行时通过VisualC++运行时完成的所有分配都在堆上完成。我可以调用HeapCreate()和以后的HeapDestroy()。如果我以某种方式确保所有分配都在新堆中完成,我就不再关心泄漏了——当我销毁第二个堆时,它们都会消失 是否有可能强制VisualC++运行时在指定的堆上进行所有分配? < p>对不起,我

我的程序使用了一个第三方动态链接库,里面有巨大的内存泄漏。我的程序和库都是VisualC++原生代码。两者都动态链接到VisualC++运行时。 < >我想将库强制另一堆,以便在库代码运行时通过VisualC++运行时完成的所有分配都在堆上完成。我可以调用
HeapCreate()
和以后的
HeapDestroy()
。如果我以某种方式确保所有分配都在新堆中完成,我就不再关心泄漏了——当我销毁第二个堆时,它们都会消失


是否有可能强制VisualC++运行时在指定的堆上进行所有分配?

< p>对不起,我的最后答案被贴了半边烤,我按下标签并输入,但不记得这是一个文本框而不是编辑器…

总之,全文如下:

您可以使用detours库钩住分配和解除分配函数,并用自己的函数替换它们:

大概是这样的:

//declare a global 
HANDLE g_currentHeap;

LPVOID WINAPI HeapAlloc(HANDLE hHeap, DWORD dwFlags, SIZE_T dwBytes) 
{ 
    return OriginalHeapAlloc(g_currentHeap, dwFlags, dwBytes);
}


BOOL WINAPI HeapFree(HANDLE hHeap, DWORD dwFlags, LPVOID lpMem)
{
    return OriginalHeapFree(g_currentHeap, dwFlags, lpMem);
}
在应用程序加载中

HANDLE g_Heaps[2];

int main()
{
    // Two heaps
    g_Heaps[0] = HeapCreate(...);
    g_Heaps[1] = HeapCreate(...);


    // Do whatevers needed to hook HeapAlloc and HeapFree and any other heap functions 
    // and redirect them to the versions above
    // Save the old function pointers so we can call them
}
然后,每次从第三方DLL调用API时,您都可以这样做

void someFn()
{
    g_currentHeap = g_Heaps[1];
    Some3rdPartyAPI();
    g_currentHeap = g_Heaps[0];

    SomeOtherFunction();

}
这应该能解决你的问题

P> C++:运行时调用新的和MalCube()的HeAPOLLC,这样这个方法就可以工作了。事实上,我相信几乎任何语言运行时都会使用win32堆函数,除非有特殊原因不使用。如果两个二进制文件以相同的方式链接到DLL,则只重定向DLL的分配充其量也很棘手

我能想到的最可靠的方法是将DLL移动到一个单独的进程中。对于只使用IDispatch接口或提供代理/存根DLL的COM DLL来说,这相当容易。否则,您需要编写一个自定义包装器-这取决于DLL的API,这需要大量的工作,或者可能是一个性能问题

如果需要保持进程内状态,可以挂接CRT分配,并将库所做的分配重定向到另一个分配器(如Win32堆)

最安全的决定是将所有调用打包到设置全局标志的库。或者,您可以检查调用堆栈,但这并不适用于所有场景。对于这两种解决方案,请注意在代码中实现但被库调用的回调


[编辑]\u尽管CRTSetAllocHook仅在调试版本中工作

你是如何链接到库的?@GMan:程序是以动态方式链接到库的。DLL是如何链接到运行时的?@Joe Gauterin:程序和DLL都是动态链接到CRT的。它们都是动态链接到同一版本的CRT吗?第三方.dll是否与您构建应用程序时使用的MSVC编译器版本相同?挂钩分配是否适用于CRT的非调试版本?您是对的,_CrtSetDebugHook也仅适用于调试版本。您可以按照rep_movsd的建议查看迂回路线,如果它们也在所有分配的发布版本中工作。否则。。。快速的谷歌搜索并不能找到任何结论。也许等待其他答复,或者将其作为新问题打开。至少在VC6中,HeapAlloc总是在调试版本中调用,在发布版本中,一个自定义内存管理器用于msot分配。我不知道这在VS2005/2008中是否发生了变化-需要验证。Visual Studio 8的CRT源代码似乎调用了HeapAlloc(),我在测试程序的发布模式下在HeapAlloc()上放置了一个断点。。。。似乎在每个malloc()和new.Detours上都会调用它,这非常有用,但需要特别小心,尤其是在有多个线程的情况下。我在调试时遇到了一些非常棘手的问题。如果您选择使用它,最好的办法是在加载任何其他DLL或启动除主DLL以外的任何线程之前初始化并设置所有迂回ed函数。否则,您可能会遇到另一个线程可能已经在您试图绕道的函数中的棘手情况。