下面是失败的代码示例.为所有内存分配调用tcmalloc,但是当调用delete时,应用程序崩溃.这对我来说真的很令人费解,因为当我在主可执行文件中创建一个函数并在那里复制代码时,完全相同的代码工作正常.
如果有人在这种情况下使用tcmalloc有任何经验,我将非常感谢您的反馈.这对我来说是一个谜.这是dll的内存模型问题(不同的堆??)?我不知道.在我看来,他们使用相同的堆.
对不起,如果这篇文章太长了.我试图提供尽可能多的信息.
谢谢.
布鲁斯
更新:作为测试,我将崩溃的共享dll更改为静态库,一切正常,直到应用程序使用不同的dll.因此无论出于何种原因,tcmalloc需要一些额外的步骤来处理共享的dll.我可以使用tcmalloc制作所有dll的静态库以进行内存分析,但知道使用共享还需要做什么才真的很好
dll与tcmalloc.
DLL头文件方法声明:
__declspec(dllexport)static std :: string GetExecutablePath();
//.cpp实现
string Parameters::GetExecutablePath() string execPathStr; char exefilePath[ MAX_PATH +1]; if ( Getmodulefilename( NulL,exefilePath,MAX_PATH ) ) { //The line of code below is where the app crashes. //It calls operator new in crt/src/new.cpp. I verifIEd the call to malloc //is forwarded to tcmalloc. *execPathStr = string(exefilePath);* //creates and deletes a temporary and then crashes long dir_pos = execPathStr.rfind( FT_DIR_SLASH ) ; execPathStr = execPathStr.substr( 0,dir_pos+1 ); } return execPathStr;}
临时字符串销毁时调用的方法:
~_String_val(){ // destroy the object typename _Alloc::template rebind<_Container_proxy>::other _Alproxy(_Alval); this->_Orphan_all(); _Dest_val(_Alproxy,this->_Myproxy); **_Alproxy.deallocate(this->_Myproxy,1);** this->_Myproxy = 0;}voID deallocate(pointer _Ptr,size_type){ // deallocate object at _Ptr,ignore size **::operator delete(_Ptr);**}This is where it crashes. the phead->nBlockUse is 0. crt/dbgdel.cpp:voID operator delete( voID *pUserData ){ //code omitted for brevity /* verify block type */ **_ASSERTE(_BLOCK_TYPE_IS_VALID(phead->nBlockUse));** //crashes here}
在将tcmalloc重建为共享DLL后,它在尝试释放内存时会在不同的位置崩溃.
afxmem.cpp:
voID __cdecl operator delete(voID* p){#if !defined(_AFX_NO_DEBUG_CRT) && defined(_DEBUG) **_free_dbg(p,_norMAL_BLOCK);** <-------- this function gets called #else free(p);#endif}
dbgheap.c:
extern "C" _CRTIMP voID __cdecl _free_dbg( voID * pUserData,int nBlockUse ){ _mlock(_HEAP_LOCK); __try { /* allocate the block */ **_free_dbg_nolock(pUserData,nBlockUse);** } __finally { /* unlock the heap */ _munlock(_HEAP_LOCK); }}extern "C" voID __cdecl _free_dbg_nolock( voID * pUserData,int nBlockUse ){ //code omitted for brevity /* * If this ASSERT fails,a bad pointer has been passed in. It may be * totally bogus,or it may have been allocated from another heap. * The pointer MUST come from the 'local' heap. */ **_ASSERTE(_CrtIsValIDHeapPointer(pUserData));** <-------- crashes here}解决方法 通过静态链接tcmalloc,每个使用它的DLL都会获得它自己的库内部状态副本(包括堆和所有指针).如果您通过tcmalloc从一个DLL分配内存并尝试从另一个DLL中删除 *** 作将失败,因为您最终访问多个堆.
将tcmalloc链接为动态库,您的问题应该消失.
总结以上是内存溢出为你收集整理的c – 有没有人能够在使用共享DLL的Windows 64位应用程序上集成tcmalloc?全部内容,希望文章能够帮你解决c – 有没有人能够在使用共享DLL的Windows 64位应用程序上集成tcmalloc?所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)