2010-11-29 3 views
4

Entschuldigung für die kryptische Frage Titel. Ich habe ein seltsames Problem und ich habe keine Ahnung, warum es passiert. Glücklicherweise ist der Code ziemlich einfach. Aber bevor wir dazu kommen, lass mich kurz meine App beschreiben. Es ist eine Multithread-App, die eine große Menge an Daten bereitstellt. So etwas wie eine In-Ram-Datenbank. Es ist möglich, mehrere "Datenbanken" darin zu haben und sie zur Laufzeit zu laden/entladen. Jetzt ist das Problem mit der Speicherfreigabe. Bitte beachten Sie den Code unten (Namen von Klassen usw. geändert werden, aber das sollte keine Rolle spielen):Seltsame Probleme mit neuen/Löschen in einer App, die meine DLL verwendet

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

Jedes Mal delete this->m_tree aufgerufen wird, stürzt das Programm ab. Der Stack-Trace sieht wie folgt aus:

 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  

Hier wird der Stack-Trace für die Zuweisung des Baumes ist:

 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 

Wie Sie das Laden sehen kann/Entladen durch einen separaten Thread durchgeführt wird speziell für erstellt diese Aufgabe. Nichts, dass ich keine ausgefallenen Dinge, keine benutzerdefinierten Heaps oder irgendetwas, keinen benutzerdefinierten Operator neu/löschen in meiner DLL oder meinem Programm. Ich habe keine Ahnung, warum das Programm in meine DLL geht und dort delete anruft, aber mit neuen passiert das nicht. Wenn ich die DeallocTree() sehen wie folgt zu ändern:

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

Dann funktioniert alles einwandfrei. Ich bin mir jedoch nicht sicher, ob das stimmt. Sollte ich etwas ähnliches für den Operator neu tun? Und wie kann ich sicher sein, dass das gleiche Problem nirgendwo sonst auftritt? Für Vollständigkeit halber bin Befestigung i auch die Stack-Trace für diese Version von 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 

Kann mir jemand erklären, was hier los ist?

EDIT:
Zur Klarstellung:
my.dll dynamisch geladen wird - VS 2008 Ausgabe: myprog.exe ': Loaded 'C: * \ Debug \ mydll.dll', Symbol geladen.
Hinweis: Ich verwende korrekt Debug-Version der DLL mit Debug-Version meines Programms und umgekehrt mit Release.
** my_tree wird wie folgt deklariert:
my_tree * m_tree; // der Baum

+0

Ist Ihre DLL statisch mit der C-Laufzeit verknüpft oder dynamisch mit msvcr90d.dll verknüpft? – Mud

+0

Wie wird 'm_tree' deklariert? – sharptooth

Antwort

6

Nun, der Hinweis scheint in den Callstacks zu sein. Im "delete" Callstack werden Sie bemerken, dass es verschiedene Löschfunktionen usw. direkt in mydll.dll aufruft. In der Zuordnung wird die Zuordnung von msvcr90d.dll durchgeführt.

Was Sie haben, ist eine/MDd (oder/MD in Release) -Flag gesetzt auf Ihre exe und ein/MTD (oder/MT in Release) auf Ihrer DLL gesetzt. Setzen Sie beide auf/MDd (oder/MD in Release) und Ihre Probleme werden verschwinden ... Grundsätzlich werden Sie sowohl die exe als auch die DLL setzen, um Anrufe an die CRT-DLL zu machen, anstatt zu versuchen, es 2 verschiedene zu tun Möglichkeiten ...

+0

+1, Klingt eine sehr wahrscheinliche Erklärung. – sharptooth

+0

Danke, das war das Problem! – PeterK

Verwandte Themen