在使用我的DLL的应用程序中使用新的/删除的奇怪问题 [英] Strange problems with new/delete in an app that uses my DLL

查看:168
本文介绍了在使用我的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;
}

每次删除this-> m_tree 被调用,程序崩溃。堆栈跟踪如下所示:

  mydll.dll!_free_base(void * pBlock = 0x0000000008496f70)行109 + 0x14字节C 
mydll.dll!_free_dbg_nolock(void * pUserData = 0x0000000008496fa0,int nBlockUse = 0x00000001)行1428 C ++
mydll.dll!_free_dbg(void * pUserData = 0x0000000008496fa0,int nBlockUse = 0x00000001)行1258 + 0xe字节C ++
mydll.dll!操作符delete(void * pUserData = 0x0000000008496fa0)行54 + 0x12字节C ++
mydll.dll!my_tree ::`向量删除析构函数()+ 0x94字节C ++
myprog .exe!SS :: DeallocTree()行57 + 0x34字节C ++
myprog.exe!SSUnloader(void * arg = 0x00000000084d6f80)行1038 C ++
msvcr90d.dll!_callthreadstart()行295 C
msvcr90d.dll!_threadstart(void * ptd = 0x00000000084dad30)行277 C

这是堆栈跟踪树的分配:

  msvcr90d.dll!malloc(unsigned __ int 64 nSize = 0x0000000000000058)行56 + 0x21字节C ++ 
msvcr90d.dll!运算符new(unsigned __int64 size = 0x0000000000000058)行59 + 0xa字节C ++
myprog.exe!SS :: AllocTree(double * * * pba = 0x0000000008458ff0,int i = 0x00000bde,int d = 0x00000010,int b = 0x00000008,int split = 0x00000001)行52 + 0xa字节C ++
myprog.exe!SSLoader(void * arg = 0x000000000843cf80)行932 C ++
msvcr90d.dll!_callthreadstart()行295 C
msvcr90d.dll!_threadstart(void * ptd = 0x0000000008440d30)行277 C

正如你所看到的,加载/卸载是由为此任务专门创建的单独线程完成的。不,我不使用任何花哨的东西,没有定制堆或任何东西,没有自定义操作符新/删除在我的程序或我的程序。我不知道为什么程序进入我的dll并且在那里调用delete但是新的,这不会发生。如果我将$ code> DeallocTree()更改为:

  void SS :: DeallocTree()
{
:: operator delete(this-> m_tree);
this-> m_tree = NULL;
}

然后一切都正常。不过,我不知道这是否正确。我应该做类似的操作员新的吗?我怎么能确定这个同样的问题不会发生在别的地方?为了完整的缘故,我也为此版本的DeallocTree()附加了堆栈跟踪:

  msvcr90d.dll! * pUserData = 0x00000000086f5fa0)行45 + 0xa字节C ++ 
myprog.exe!SS :: DeallocTree()行58 C ++
myprog.exe!SSUnloader(void * arg = 0x0000000008735f80)行1038 C ++
msvcr90d.dll!_callthreadstart()行295 C
msvcr90d.dll!_threadstart(void * ptd = 0x0000000008739d30)行277 C

有人向我解释这里发生了什么吗?



编辑:

要澄清:

my.dll是动态加载的 - VS 2008输出:
myprog.exe':加载'C:* \Debug\mydll.dll' ,符号加载。

注意:我正在使用调试版本的dll与我的程序的调试版本,反之亦然释放。

** my_tree声明为:
my_tree * m_tree; //树

解决方案

好的线索似乎在调用堆栈中。在删除调用堆栈中,您会注意到它直接在mydll.dll中调用各种删除功能。在分配中,分配正由msvcr90d.dll执行。



你有一个/ MDD(或/ MD在发布)标志设置在你的exe和一个/您的dll上设置MTd(或/发行版)。将它们设置为/ MDd(或发布中的/ MD),并且您的问题将消失...基本上,您将设置EXE和dll,以使电话进入CRT dll,而不是尝试做2个不同的方式...


sorry for the cryptic question title. I'm having a strange problem and i have no idea why it is happening. Fortunately, the code involved is pretty simple. But beofre we get to it, let me briefly describe my app. It is a multithreaded app that serves a large amount of data. Something like an in-ram database. It is possible to have multiple "databases" in it and load/unload them at runtime. Now the problem is with the memory deallocation. Please see the code bellow (names of classes etc are changed, but this should not matter):

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;
}

Every time delete this->m_tree is called, the program crashes. The stack trace looks like this:

     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       

Here is the stack trace for the allocation of the tree:

     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

As you can see the loading/unloading is done by a separate thread specifically created for this task. Nothe that i do not use any fancy things, no custom heaps or anything, no custom operator new/delete in my dll or my program. I have no idea why does the program go into my dll and call delete there but with new, this does not happen. If I change the DeallocTree() to look like this:

void SS::DeallocTree()
{
    ::operator delete( this->m_tree );
    this->m_tree = NULL;
}

Then everything works fine. However, i am not sure if this is correct. Shouldnt i do something similar for operator new? And how can i be sure this same problem does not occur anywhere else? For completness sake i am also attaching the stack trace for this version of 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

Can someone explain to me what is going on here?

EDIT:
To clarify:
my.dll is loaded dynamically - VS 2008 output: myprog.exe': Loaded 'C:*\Debug\mydll.dll', Symbols loaded.
Note: i am correctly using debug version of the dll with debug version of my program and vice versa with release.
**my_tree is declared as:
my_tree* m_tree; // the tree

解决方案

Well the clue appears to be in the callstacks. In the "delete" callstack you'll notice it is calling various delete functions etc directly in mydll.dll. In the allocation the allocation is being performed by msvcr90d.dll.

What you have is a /MDd (or /MD in release) flag set on your exe and a /MTd (or /MT in release) set on your dll. Set them both to /MDd (or /MD in release) and your problems will go away ... Basically you'll be setting both the exe and the dll to make calls across to the CRT dll instead of trying to do it 2 different ways ...

这篇关于在使用我的DLL的应用程序中使用新的/删除的奇怪问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆