2010-11-29 9 views
4

謎めいた質問のタイトルに申し訳ありません。私は奇妙な問題を抱えており、なぜそれが起こっているのか分かりません。幸いにも、関係するコードはかなり簡単です。しかし私たちはそれに着く、簡単に私のアプリを説明してみましょう。これは、大量のデータを処理するマルチスレッドアプリケーションです。 in-ramデータベースのようなもの。複数の "データベース"を持ち、実行時にロード/アンロードすることは可能です。今問題は、メモリの割り当てを解除することです。 (クラスなどの名前が変更されているが、これは問題ではありません)コード怒鳴るを参照してください。私のDLLを使用するアプリケーションで新規/削除に奇妙な問題が発生しました

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 

この仕事。 not notは、私のdllや私のプログラムでは、任意のファンシーなこと、カスタムヒープや何も、カスタム演算子の新しい/削除を使用しないでください。私はなぜプログラムが私のdllに入ってそこに削除を呼び出すのかわからないが、新しいものではこれは起こらない。私はDeallocTree()を変更する場合は、このように見えるように:

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

その後、すべてが正常に動作します。しかし、これが正しいかどうかはわかりません。私はオペレータnewのために何か類似したことをしてはいけませんか?そして、どのように私はこの同じ問題がどこにも起こらないことを確かめることができますか? completness期すために、私はまた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 

は、誰かがここで何が起こっているか私に説明できますか?

EDIT:
明確にする:
my.dllが動的にロードされる - VS 2008の出力: MYPROG.EXE ':ロード 'C:* \デバッグ\のMYDLL.DLL'、ロードされたシンボル。
注:私は正しく、私のプログラムのデバッグバージョンではdllのデバッグバージョンを使用しています。逆もまた同様です。
** my_treeは次のように宣言されています。
my_tree * m_tree; //木の葉

+0

dllは静的にCランタイムにリンクされていますか、またはmsvcr90d.dllに動的にリンクされていますか? – Mud

+0

'm_tree'はどのように宣言されていますか? – sharptooth

答えて

6

まあ、手がかりはコールスタックにあるようです。 "delete"コールスタックでは、mydll.dll内のさまざまな削除関数などを直接呼び出していることがわかります。割り当てでは、割り当てはmsvcr90d.dllによって実行されています。

exeに設定された/ MDd(または/ MDのリリースで)フラグとdllに設定された/ MTd(またはリリースのMT)です。それらを/ MDd(またはリリースでは/ MD)に設定すると、問題は消えてしまいます...基本的には、exeとdllの両方を設定して、CRT dllを呼び出します。方法...

+0

+1、考えられる可能性が高いと思われます。 – sharptooth

+0

ありがとう、それは問題でした! – PeterK

関連する問題