Strange problems with new/delete in an app that us

2019-06-27 06:40发布

问题:

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

回答1:

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 ...



标签: c++ memory dll