在使用我的DLL的应用程序中新/删除的奇怪问题

时间:2010-11-29 08:33:17

标签: c++ memory dll

抱歉这个神秘的问题标题。我有一个奇怪的问题,我不知道它为什么会发生。幸运的是,涉及的代码非常简单。但是,我们得到它,让我简要描述我的应用程序。它是一个多线程应用程序,可以提供大量数据。类似于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; //树

1 个答案:

答案 0 :(得分:6)

好的线索似乎是在callstacks中。在“删除”调用堆栈中,您会注意到它直接在mydll.dll中调用各种删除函数等。在分配中,分配由msvcr90d.dll执行。

你所拥有的是你的exe上设置的/ MDd(或发布时的/ MD)标志和你的dll上设置的/ MTd(或释放中的/ MT)。将它们设置为/ MDd(或发布中的/ MD)并且您的问题将消失...基本上您将设置exe和dll来调用CRT dll而不是尝试执行它2个不同方式......