2010-12-28 10 views
1

Ich habe ein Problem, das zu einem ungültigen Speicherblock erscheint, der während eines Boost-Anrufs an Boost:runtime:cla::parser::~parser auftritt. Wenn das globale Lösch für dieses Objekt aufgerufen wird, C++ behauptet auf dem Speicherblock als ein ungültiger:Boost verursacht einen ungültigen Block beim Überladen neuer/löscht Operatoren

dbgdel.cpp(52): 

/* verify block type */ 
_ASSERTE(_BLOCK_TYPE_IS_VALID(pHead->nBlockUse)); 

Eine Untersuchung ergab, ich habe, dass das Problem aufgrund einer globalen Überlastung des neuen passiert/löschen Operatoren. Diese Überladungen werden in einer separaten DLL platziert. Ich entdeckte, dass das Problem nur auftritt, wenn diese DLL in RELEASE kompiliert wird, während die Hauptanwendung in DEBUG kompiliert wird.

Also dachte ich, dass die Release/Debug Build Flavors möglicherweise ein Problem wie dieses in Boost/CRT beim Überladen neuer/löschender Operatoren verursacht haben. Also habe ich versucht, _malloc_dbg und _free_dbg explizit mit den Überladungsfunktionen auch im Freigabemodus aufzurufen, aber das ungültige Heapblockproblem wurde nicht gelöst.

Eine Idee, was die Ursache des Problems ist? Ist diese Situation lösbar?

Ich sollte betonen, dass das Problem erst begann, als ich begann, Boost zu verwenden. Zuvor hat CRT sich nie über einen ungültigen Speicherblock beschwert. Könnte es also ein interner Boost Bug sein?

Danke!

Antwort

2

entdeckte ich, dass das Problem nur geschieht, wenn das DLL in RELEASE kompiliert wird, während die Hauptanwendung in DEBUG kompiliert wird

Im Allgemeinen Sie keine Module, die die Freisetzung CRT mit dem Debug-CRT verwenden mischen können, wenn Die Speicherzuweisung von einem Laufzeittyp wird von der anderen Laufzeitumgebung freigegeben (es können andere Probleme auftreten, aber Speicherzuweisungsprobleme scheinen am häufigsten aufzutauchen).

Die Lösung besteht darin, Module zu verwenden, die gegen die Debug-Laufzeit miteinander erstellt werden, und Module, die gegen die Release-Laufzeit miteinander gebaut werden - mischen Sie die beiden nicht.

Erklärung von Microsoft finden Sie hier: http://msdn.microsoft.com/en-us/library/ms235460.aspx

weil jede Kopie der CRT-Bibliothek einen eigenen Heap-Manager hat, Gedächtnis und vorbei über eine DLL-Grenze den Zeiger in einer CRT-Bibliothek Zuweisen von einem befreit werden Eine andere Kopie der CRT-Bibliothek ist eine mögliche Ursache für Heap-Beschädigung.

+0

Michael, Danke für die Antwort. Da beide neuen/delete in der gleichen RELEASE DLL gemacht werden, verstehe ich nicht, wie diese Mischung wirklich passiert. Der gleiche Speicherblock, der in der DLL zugewiesen wurde, wird auch von der gleichen DLL wegen der neuen/Lösch-Überladung freigegeben, die in derselben DLL implemented. Vor der Verwendung von Boost beklagte sich CRT nie darüber, obwohl ich seine Bibliotheken ausgiebig verwendete. Nur mit Boost passiert es und auf diesem speziellen Parser-Objekt. Das lässt mich ahnungslos ... – user555746

+0

@ user555746: das ist interessant ... und nicht das, was ich auf den ersten Gedanken erwarten würde. Gibt es einen relativ kleinen Repro-Fall, der einen Standard-Boost-Download verwendet? –

+0

Alles, was ich mache, ist wie folgt: 1. Erstellen Sie eine EXE mit Standard-Boost-Bibliothek, um einen Einheitentest mit Boost-API zu implementieren - Sie können den Unit-Test leer lassen 2. Erstellen Sie eine einfache DLL und erstellen Sie zwei exportierte Funktionen, die wie neu funktionieren/Löschen und einfach malloc/free innerhalb 3. Innerhalb der EXE überladen die neue/global löschen und rufen Sie die exportierten Funktionen aus der DLL, um den Anruf zu delegieren 4.Führen Sie die Anwendung aus, und während des CRT-Teardowns sollten Sie das obige ASSERT für den boost :: runtime :: cla :: parser :: ~ Parser erhalten, der wahrscheinlich eine der internen Klassen ist, die Boost für das Unit-Test-Framework verwendet. – user555746

Verwandte Themen