Laufzeitbibliothek als "Multithreaded DLL" sorgt für Memory Leak
-
Hi,
ich habe eine DLL, in der ist eine Klasse, die am Ende des Destruktors _CrtDumpMemoryLeaks(); aufruft. Wenn ich die normale Laufzeitbibliothek verwende, dumpt er mir keine Memory Leaks in die Debugkonsole.
Verwende ich aber Multithreaded DLL (debug) und für die Anwendung, die die DLL benutzt Multithreaded (debug), dann werden plötzlich zwei komische Memory Leaks gedumped:Detected memory leaks! Dumping objects -> {48} normal block at 0x00891DC0, 33 bytes long. Data: < C > 00 43 00 CD CD CD CD CD CD CD CD CD CD CD CD CD {47} normal block at 0x00891E10, 40 bytes long. Data: < |L > 14 7C 4C 10 16 00 00 00 00 00 00 00 00 00 00 00 Object dump complete.
Weiß einer, woran das liegt?
ChrisM
-
Mach nen doppelklick auf die Meldung, dann müsste er dort hin springen wo es erzeugt wird (jedenfalls bei .NET).
-
Nein, ich hör nur einen Piepston. Kann die Meldung auch nicht im Debugfenster markieren (durch Doppelklick), wie Compilerfehler im Ausgabefenster des Compilers.
ChrisM
-
OK, dann halt anders. Ich suche eine Memory Leak Findungsmöglichkeit, die den folgenden Bedingungen entspricht:
- Keine new-/delete-Überladungen, weil mein Compiler einen Bug hat, der dann das Benutzen von std::string unmöglich macht (siehe C++ Forum)
- Kostenlos (also kein BoundsChecker oder sowas)
- Auch mit (DLL) Multithreaded Laufzeitbibliothek funktionsfähigWenn ihr euch beim letzten net sicher seit, sagts einfach mal und ich teste
ChrisM
-
ist doch egal ob die 2 fehler da kommen, oder nicht! oder mach mal ein ganz kurzes beispiel wie man das testen kann mit der dll und wo das problem dann trotzdem noch auftritt.
-
Verwende ich aber Multithreaded DLL (debug) und für die Anwendung, die die DLL benutzt Multithreaded (debug),
Und warum machst du das so? Misch die doch nicht und nimm für beides die selbe.
-
Ich verwende unterschiedliche Einstellungen, weil ich mal ein Problem mit einem virtuellen Destruktoraufruf hatte und da wurde mir gesagt, ich müsse bei der DLL auf Multithreaded DLL (debug) stellen und bei der EXE, die die DLL benutzt (anderes Projekt) auf Multithreaded (debug).
Sonst hab ich da glaub ich immer einen Dialog gekriegt "damage after normal block" oder sowas, aber mit diesen Einstellungen gings dann.
Die Einstellungen kannst du unter Projekteinstellungen/C++/Code Generation/Laufzeitbibliothek machen.ChrisM
-
Hi,
also ich hatte dir das auf jeden Fall nicht so gesagt.
Debug Assertion failed bei delete
EXE Debug -> Multithreaded-Debug-DLL
DLL Debug -> Multithreaded-Debug-DLL...
Wichtig ist das EXE und DLL gegen die gleiche Laufzeitbibliothek linken.
-
Danke, was hätte ich jetzt ohne dich gemacht
Aber leider gehts immer noch nicht
Mir scheint sogar, als wäre jetzt noch ein Memory Leak dazugekommenChrisM
-
Hi,
ich hab das ganze mal mit einer kleinen Konsolenanwendung und Visual C++ 7 getestet:
#include <crtdbg.h> int main() { int* i = new int; _CrtDumpMemoryLeaks(); return 0; }
Es wurde immer nur der "echte" Memory-Leak angezeigt, egal ob mit Singlethreaded-Debug oder Multithreaded-Debug-DLL.
-
Moment, ich mach mal ein kleines Testprojekt ...
ChrisM
-
So, hab meine DLL jetzt auf das wesentliche minimiert (alle Dateien von der Erstellung ausgeschlossen, außer der Hauptdatei und in der alles außer Konstruktor, Destruktor und der statischen Memberfunktion, die die Leaks dumpen soll, auskommentiert) und er findet keine Leak mehr!!
Ich aktivier jetzt wieder langsam alles und sag dann, worans lag, ok?ChrisM
-
Komisch, bei den harmlosesten Klassen, kommen wieder Memory Leaks. Ich hab z.B. Color.cpp und Color.h wieder kompilieren lassen und jetzt ist das Leak wieder da. Die Dateien sehen so aus:
Color.h
#ifndef THETAENGINEINCLUDE_COLOR #define THETAENGINEINCLUDE_COLOR #include "Global.h" class thetaColor { public: THETADLL thetaColor(); THETADLL thetaColor(unsigned long dwRed, unsigned long dwGreen, unsigned long dwBlue, unsigned long dwAlpha); THETADLL thetaColor(unsigned long dwARGB); THETADLL void Set(unsigned long dwRed, unsigned long dwGreen, unsigned long dwBlue, unsigned long dwAlpha); THETADLL void SetRed(unsigned long dwRed); THETADLL void SetGreen(unsigned long dwGreen); THETADLL void SetBlue(unsigned long dwBlue); THETADLL void SetAlpha(unsigned long dwAlpha); THETADLL unsigned long dwGetAsDWORD() const; THETADLL unsigned long dwGetRed() const; THETADLL unsigned long dwGetGreen() const; THETADLL unsigned long dwGetBlue() const; THETADLL unsigned long dwGetAlpha() const; protected: unsigned long m_dwRed, m_dwGreen, m_dwBlue, m_dwAlpha; }; #endif
Color.cpp
#include "Color.h" thetaColor::thetaColor() { m_dwRed = m_dwGreen = m_dwBlue = m_dwAlpha = 0; } thetaColor::thetaColor(unsigned long dwRed, unsigned long dwGreen, unsigned long dwBlue, unsigned long dwAlpha) { m_dwRed = dwRed; m_dwGreen = dwGreen; m_dwBlue = dwBlue; m_dwAlpha = dwAlpha; } thetaColor::thetaColor(unsigned long dwARGB) { // to do } void thetaColor::Set(unsigned long dwRed, unsigned long dwGreen, unsigned long dwBlue, unsigned long dwAlpha) { m_dwRed = dwRed; m_dwGreen = dwGreen; m_dwBlue = dwBlue; m_dwAlpha = dwAlpha; } void thetaColor::SetRed(unsigned long dwRed) { m_dwRed = dwRed; } void thetaColor::SetGreen(unsigned long dwGreen) { m_dwGreen = dwGreen; } void thetaColor::SetBlue(unsigned long dwBlue) { m_dwBlue = dwBlue; } void thetaColor::SetAlpha(unsigned long dwAlpha) { m_dwAlpha = dwAlpha; } unsigned long thetaColor::dwGetAsDWORD() const { // to do return 0x00000000; } unsigned long thetaColor::dwGetRed() const { return m_dwRed; } unsigned long thetaColor::dwGetGreen() const { return m_dwGreen; } unsigned long thetaColor::dwGetBlue() const { return m_dwBlue; } unsigned long thetaColor::dwGetAlpha() const { return m_dwAlpha; }
THETADLL ist einfach ein #define für __declspec(dllexport)! (im DLL-Projekt, sonst natürlich dllimport)
ChrisM
-
Kann dir da leider nicht weiterhelfen, aber durchsuch mal Google Groups dannach.
z.B. so :p
-
Schön, aber mein ganzer STL-Teil ist ja eh auskommentiert und in Color.cpp kommt ja kein String vor!
ChrisM
-
Mach uns doch mal das kleinst-mögliche Beispiel fertig, wo diese Leaks dann immer noch entstehen, so das wir selbst mal rumspielen können. Am besten, wenn es geht, in einem Projekt (also ohne DLL) und alles in eine Datei.
-
Ja, aber ich kanns net rekonstruieren, ich versuch jetzt mal durch Auskommentieren in Color.cpp den Fehlergrund zu suchen und dann sag ich euch, woran es liegt.
ChrisM
-
Oder lad das Ding mal auf deinen Homepage-Server und lass uns mitprobieren.
-
Hab das Problem gefunden: Ich kriege die Leak-Warnung, wenn ich irgendwo std::string verwende (also kommts doch von der STL). Das komische ist nur, ich kriege die Warnungen nicht, wenn ich nur string inkludiere, aber std::string nicht verwende (noch nicht so komisch), aber erst hab ich gedacht, es sind vielleicht statische Member von std::string, aber das kann ja nicht sein, denn die würden ja erst erzeugt werden, wenn die Funktion aufgerufen wird, aber meine Testfunktion, die std::string verwendet, wird nirgends aufgerufen!
ChrisM
-
*Code will* :p
-
Gerne:
void Test() { std::string strTest; }
Im Header wird diese Funktion in die DLL exportiert, aber sie wird nirgends aufgerufen. Trotzdem seh ich die beiden Memory Leaks, kommentier ich sie aus (gibt keinen Fehler, wird ja nirgends aufgerufen) hab ich keine Memory Leaks mehr!
ChrisM