抱歉这个神秘的问题标题。我有一个奇怪的问题,我不知道它为什么会发生。幸运的是,涉及的代码非常简单。但是,我们得到它,让我简要描述我的应用程序。它是一个多线程应用程序,可以提供大量数据。类似于in-ram数据库的东西。可以在其中包含多个“数据库”,并在运行时加载/卸载它们。现在的问题是内存释放。请参阅下面的代码(类的名称等已更改,但这无关紧要):
void SS::AllocTree( double*** pba, int i, int d, int b, int split )
{
this->m_tree = new my_tree( pba, i, d, b, split );
}
void SS::DeallocTree()
{
delete this->m_tree;
this->m_tree = NULL;
}
每次调用delete this->m_tree
时,程序都会崩溃。堆栈跟踪如下所示:
mydll.dll!_free_base(void * pBlock=0x0000000008496f70) Line 109 + 0x14 bytes C
mydll.dll!_free_dbg_nolock(void * pUserData=0x0000000008496fa0, int nBlockUse=0x00000001) Line 1428 C++
mydll.dll!_free_dbg(void * pUserData=0x0000000008496fa0, int nBlockUse=0x00000001) Line 1258 + 0xe bytes C++
mydll.dll!operator delete(void * pUserData=0x0000000008496fa0) Line 54 + 0x12 bytes C++
mydll.dll!my_tree::`vector deleting destructor'() + 0x94 bytes C++
myprog.exe!SS::DeallocTree() Line 57 + 0x34 bytes C++
myprog.exe!SSUnloader(void * arg=0x00000000084d6f80) Line 1038 C++
msvcr90d.dll!_callthreadstart() Line 295 C
msvcr90d.dll!_threadstart(void * ptd=0x00000000084dad30) Line 277 C
以下是树分配的堆栈跟踪:
msvcr90d.dll!malloc(unsigned __int64 nSize=0x0000000000000058) Line 56 + 0x21 bytes C++
msvcr90d.dll!operator new(unsigned __int64 size=0x0000000000000058) Line 59 + 0xa bytes C++
myprog.exe!SS::AllocTree(double * * * pba=0x0000000008458ff0, int i=0x00000bde, int d=0x00000010, int b=0x00000008, int split=0x00000001) Line 52 + 0xa bytes C++
myprog.exe!SSLoader(void * arg=0x000000000843cf80) Line 932 C++
msvcr90d.dll!_callthreadstart() Line 295 C
msvcr90d.dll!_threadstart(void * ptd=0x0000000008440d30) Line 277 C
正如您所看到的,加载/卸载是由专门为此任务创建的单独线程完成的。不,我不使用任何花哨的东西,没有自定义堆或任何东西,在我的dll或我的程序中没有自定义操作符new / delete。我不知道为什么程序进入我的dll并在那里调用删除但是新的,这不会发生。如果我将DeallocTree()
更改为如下所示:
void SS::DeallocTree()
{
::operator delete( this->m_tree );
this->m_tree = NULL;
}
然后一切正常。但是,我不确定这是否正确。我不应该为运营商新做类似的事吗?我怎么能确定在其他任何地方都不会出现同样的问题?为了完整起见,我还附加了此版本的DeallocTree()的堆栈跟踪:
msvcr90d.dll!operator delete(void * pUserData=0x00000000086f5fa0) Line 45 + 0xa bytes C++
myprog.exe!SS::DeallocTree() Line 58 C++
myprog.exe!SSUnloader(void * arg=0x0000000008735f80) Line 1038 C++
msvcr90d.dll!_callthreadstart() Line 295 C
msvcr90d.dll!_threadstart(void * ptd=0x0000000008739d30) Line 277 C
有人可以向我解释这里发生了什么吗?
编辑:
澄清:
my.dll是动态加载的 - VS 2008输出:
myprog.exe':已加载'C:* \ Debug \ mydll.dll',符号已加载。
注意:我正在使用我的程序的调试版本的调试版本的DLL,反之亦然
** my_tree声明为: my_tree * m_tree; //树
答案 0 :(得分:6)
好的线索似乎是在callstacks中。在“删除”调用堆栈中,您会注意到它直接在mydll.dll中调用各种删除函数等。在分配中,分配由msvcr90d.dll执行。
你所拥有的是你的exe上设置的/ MDd(或发布时的/ MD)标志和你的dll上设置的/ MTd(或释放中的/ MT)。将它们设置为/ MDd(或发布中的/ MD)并且您的问题将消失...基本上您将设置exe和dll来调用CRT dll而不是尝试执行它2个不同方式......