sehr langsames Beenden von Programmen



  • Hallo

    Ich schreibe gerade eine dialogfeldbasierte Anwendung mit einigen Tabs. Wenn ich diese nun beende, dann ist mir aufgefallen, dass im VS es immer eine Weile dauert, bis dieser wieder in den Bearbeitungmodus zurückgeht, also den RunModus verlässt (mir fehlen die richtgen Worte, ich hoffe, dass ihr versteht, was ich meine) Nun habe ich bemerkt, dass im Outputfenster nun die ganze Zeit die Zeilen des Projektes durchgezählt werden und folgenden Meldung im Fenster steht:

    Data: < ~ > 8C 88 7E 00 08 00 00 00 80 00 00 00 01 00 00 00
    {2723} normal block at 0x01431648, 274 bytes long.
    Data: < ~ > 8C 88 7E 00 07 00 00 00 80 00 00 00 01 00 00 00
    {2722} normal block at 0x014314F8, 274 bytes long.
    Data: < ~ > 8C 88 7E 00 06 00 00 00 80 00 00 00 01 00 00 00
    {2721} normal block at 0x014313A8, 274 bytes long.
    Data: < ~ > 8C 88 7E 00 07 00 00 00 80 00 00 00 01 00 00 00
    {2720} normal block at 0x01431258, 274 bytes long.
    Data: < ~ > 8C 88 7E 00 09 00 00 00 80 00 00 00 01 00 00 00
    {2719} normal block at 0x01431108, 274 bytes long.
    Data: < ~ > 8C 88 7E 00 0A 00 00 00 80 00 00 00 01 00 00 00
    {2718} normal block at 0x01430FB8, 274 bytes long.
    Data: < ~ > 8C 88 7E 00 06 00 00 00 80 00 00 00 01 00 00 00
    {2717} normal block at 0x01430E68, 274 bytes long.
    Data: < ~ > 8C 88 7E 00 06 00 00 00 80 00 00 00 01 00 00 00
    {2716} normal block at 0x01430D18, 274 bytes long.
    Data: < ~ > 8C 88 7E 00 06 00 00 00 80 00 00 00 01 00 00 00
    {2715} normal block at 0x01430BC8, 274 bytes long.
    Data: < ~ > 8C 88 7E 00 07 00 00 00 80 00 00 00 01 00 00 00
    {2714} normal block at 0x01430A78, 274 bytes long.
    Data: < ~ > 8C 88 7E 00 09 00 00 00 80 00 00 00 01 00 00 00
    {2713} normal block at 0x01424340, 274 bytes long.
    Data: < ~ > 8C 88 7E 00 08 00 00 00 80 00 00 00 01 00 00 00
    {2712} normal block at 0x014241F0, 274 bytes long.
    Data: < ~ > 8C 88 7E 00 07 00 00 00 80 00 00 00 01 00 00 00
    {2711} normal block at 0x014240A0, 274 bytes long.
    Data: < ~ > 8C 88 7E 00 07 00 00 00 80 00 00 00 01 00 00 00
    {2710} normal block at 0x01423F50, 274 bytes long.
    Data: < ~ > 8C 88 7E 00 06 00 00 00 80 00 00 00 01 00 00 00
    {2709} normal block at 0x01423E00, 274 bytes long.
    Data: < ~ > 8C 88 7E 00 06 00 00 00 80 00 00 00 01 00 00 00
    {2708} normal block at 0x01423CB0, 274 bytes long.
    Data: < ~ > 8C 88 7E 00 06 00 00 00 80 00 00 00 01 00 00 00
    {2707} normal block at 0x01423B60, 274 bytes long.
    Data: < ~ > 8C 88 7E 00 09 00 00 00 80 00 00 00 01 00 00 00
    {2706} normal block at 0x01423A10, 274 bytes long.
    Data: < ~ > 8C 88 7E 00 05 00 00 00 80 00 00 00 01 00 00 00
    {2705} normal block at 0x014238C0, 274 bytes long.
    Data: < ~ > 8C 88 7E 00 06 00 00 00 80 00 00 00 01 00 00 00
    {2704} normal block at 0x01423770, 274 bytes long.
    Data: < ~ > 8C 88 7E 00 06 00 00 00 80 00 00 00 01 00 00 00
    {2703} normal block at 0x01423620, 274 bytes long.
    Data: < ~ > 8C 88 7E 00 07 00 00 00 80 00 00 00 01 00 00 00
    {2702} normal block at 0x014234D0, 274 bytes long.
    Data: < ~ > 8C 88 7E 00 05 00 00 00 80 00 00 00 01 00 00 00
    {2701} normal block at 0x01423380, 274 bytes long.
    Data: < ~ > 8C 88 7E 00 04 00 00 00 80 00 00 00 01 00 00 00
    {2700} normal block at 0x01423230, 274 bytes long.
    Data: < ~ > 8C 88 7E 00 0A 00 00 00 80 00 00 00 01 00 00 00
    {2699} normal block at 0x014230E0, 274 bytes long.
    Data: < ~ > 8C 88 7E 00 04 00 00 00 80 00 00 00 01 00 00 00
    {2697} normal block at 0x0142F1B0, 274 bytes long.
    Data: < ~ > 8C 88 7E 00 04 00 00 00 80 00 00 00 01 00 00 00
    {2696} normal block at 0x0142F060, 274 bytes long.
    Data: < ~ > 8C 88 7E 00 08 00 00 00 80 00 00 00 01 00 00 00
    {2695} normal block at 0x0142EF10, 274 bytes long.
    Data: < ~ > 8C 88 7E 00 05 00 00 00 80 00 00 00 01 00 00 00
    {2694} normal block at 0x0142EDC0, 274 bytes long.
    Data: < ~ > 8C 88 7E 00 04 00 00 00 80 00 00 00 01 00 00 00
    {2693} normal block at 0x0142EC70, 274 bytes long.
    Data: < ~ > 8C 88 7E 00 06 00 00 00 80 00 00 00 01 00 00 00
    {2692} normal block at 0x0142EB20, 274 bytes long.
    Data: < ~ > 8C 88 7E 00 08 00 00 00 80 00 00 00 01 00 00 00
    {2691} normal block at 0x0142E9D0, 274 bytes long.
    Data: < ~ > 8C 88 7E 00 0A 00 00 00 80 00 00 00 01 00 00 00
    {2690} normal block at 0x0142E880, 274 bytes long.
    Data: < ~ > 8C 88 7E 00 04 00 00 00 80 00 00 00 01 00 00 00
    {2689} normal block at 0x0142E730, 274 bytes long.
    Data: < ~ > 8C 88 7E 00 0F 00 00 00 80 00 00 00 01 00 00 00
    {2688} normal block at 0x0142E5E0, 274 bytes long.
    Data: < ~ > 8C 88 7E 00 07 00 00 00 80 00 00 00 01 00 00 00
    {2687} normal block at 0x0142E490, 274 bytes long.
    Data: < ~ > 8C 88 7E 00 07 00 00 00 80 00 00 00 01 00 00 00
    {2686} normal block at 0x0142E340, 274 bytes long.
    Data: < ~ > 8C 88 7E 00 08 00 00 00 80 00 00 00 01 00 00 00
    {2685} normal block at 0x0142E1F0, 274 bytes long.
    Data: < ~ > 8C 88 7E 00 06 00 00 00 80 00 00 00 01 00 00 00
    {2684} normal block at 0x0142E0A0, 274 bytes long.
    Data: < ~ > 8C 88 7E 00 08 00 00 00 80 00 00 00 01 00 00 00
    {2683} normal block at 0x0142DF50, 274 bytes long.
    Data: < ~ > 8C 88 7E 00 08 00 00 00 80 00 00 00 01 00 00 00
    {2682} normal block at 0x0142DE00, 274 bytes long.
    Data: < ~ > 8C 88 7E 00 07 00 00 00 80 00 00 00 01 00 00 00
    {2681} normal block at 0x0142DCB0, 274 bytes long.
    Data: < ~ > 8C 88 7E 00 05 00 00 00 80 00 00 00 01 00 00 00
    {2680} normal block at 0x0142DB60, 274 bytes long.
    Data: < ~ > 8C 88 7E 00 09 00 00 00 80 00 00 00 01 00 00 00
    {2679} normal block at 0x0142DA10, 274 bytes long.
    Data: < ~ > 8C 88 7E 00 08 00 00 00 80 00 00 00 01 00 00 00
    {2678} normal block at 0x0142D8C0, 274 bytes long.
    Data: < ~ > 8C 88 7E 00 03 00 00 00 80 00 00 00 01 00 00 00
    {2677} normal block at 0x0142D770, 274 bytes long.
    Data: < ~ > 8C 88 7E 00 05 00 00 00 80 00 00 00 01 00 00 00
    {2676} normal block at 0x0142D620, 274 bytes long.
    Data: < ~ > 8C 88 7E 00 04 00 00 00 80 00 00 00 01 00 00 00
    {2675} normal block at 0x0142D4D0, 274 bytes long.
    Data: < ~ > 8C 88 7E 00 05 00 00 00 80 00 00 00 01 00 00 00
    {2674} normal block at 0x0142D380, 274 bytes long.
    Data: < ~ > 8C 88 7E 00 06 00 00 00 80 00 00 00 01 00 00 00
    {2673} normal block at 0x0142D230, 274 bytes long.
    Data: < ~ > 8C 88 7E 00 06 00 00 00 80 00 00 00 01 00 00 00
    {2672} normal block at 0x0142D0E0, 274 bytes long.
    Data: < ~ > 8C 88 7E 00 08 00 00 00 80 00 00 00 01 00 00 00
    {2671} normal block at 0x0142CF90, 274 bytes long.
    Data: < ~ > 8C 88 7E 00 08 00 00 00 80 00 00 00 01 00 00 00
    {2670} normal block at 0x0142CE40, 274 bytes long.
    Data: < ~ > 8C 88 7E 00 05 00 00 00 80 00 00 00 01 00 00 00
    {2669} normal block at 0x0142CCF0, 274 bytes long.
    Data: < ~ > 8C 88 7E 00 06 00 00 00 80 00 00 00 01 00 00 00
    {2668} normal block at 0x0142CBA0, 274 bytes long.
    Data: < ~ > 8C 88 7E 00 04 00 00 00 80 00 00 00 01 00 00 00
    {2667} normal block at 0x0142CA50, 274 bytes long.
    Data: < ~ > 8C 88 7E 00 07 00 00 00 80 00 00 00 01 00 00 00
    {2666} normal block at 0x0142C900, 274 bytes long.
    Data: < ~ > 8C 88 7E 00 07 00 00 00 80 00 00 00 01 00 00 00
    {2665} normal block at 0x0142C7B0, 274 bytes long.
    Data: < ~ > 8C 88 7E 00 03 00 00 00 80 00 00 00 01 00 00 00
    {2664} normal block at 0x0142C660, 274 bytes long.
    Data: < ~ > 8C 88 7E 00 05 00 00 00 80 00 00 00 01 00 00 00
    {2663} normal block at 0x0142C510, 274 bytes long.
    Data: < ~ > 8C 88 7E 00 07 00 00 00 80 00 00 00 01 00 00 00
    {2662} normal block at 0x0142C3C0, 274 bytes long.
    Data: < ~ > 8C 88 7E 00 06 00 00 00 80 00 00 00 01 00 00 00
    {2661} normal block at 0x0142C270, 274 bytes long.
    Data: < ~ > 8C 88 7E 00 08 00 00 00 80 00 00 00 01 00 00 00
    {2660} normal block at 0x0142C120, 274 bytes long.
    Data: < ~ > 8C 88 7E 00 07 00 00 00 80 00 00 00 01 00 00 00
    {2659} normal block at 0x0142BFD0, 274 bytes long.
    Data: < ~ > 8C 88 7E 00 04 00 00 00 80 00 00 00 01 00 00 00
    {2658} normal block at 0x0142BE80, 274 bytes long.
    Data: < ~ > 8C 88 7E 00 05 00 00 00 80 00 00 00 01 00 00 00
    {2657} normal block at 0x0142BD30, 274 bytes long.
    Data: < ~ > 8C 88 7E 00 08 00 00 00 80 00 00 00 01 00 00 00
    {2656} normal block at 0x0142BBE0, 274 bytes long.
    Data: < ~ > 8C 88 7E 00 0E 00 00

    Das ist jetzt nur eine kurzer Ausschnitt. Weiß jemand damit etwas anzufangen?

    Vielen Dank für eure Mühen.

    chrische



  • Das sieht ganz einfach nach einem gewaltigen Memory-Leck aus, das du vergessen hast zu stopfen. Das heißt du solltest dir Gedanken machen, die per new angeforderten Speicherbereiche auch wieder freizugeben, wenn du sie nicht mehr brauchst.

    (in C++ gibt es keinen Garbage Collector, der sich darum kümmern könnte ;))



  • Hallo

    Hmm. So etwas dachte ich mir schon, nur fordere ich eigentlich keinen Speicher per new an. zumndest nicht direkt. Ich werde jetzt mal nachschauen, ob ich es irgendwo indirekt tue.

    chrische



  • Schreib mal ein #define new DEBUG_NEW an den Anfang deines Programms, dann kannst du schonmal einschränken, wo der Speicher verbraten wird. Wenn das zu ungenau ist, solltest du einen Leak-Detektor anschaffen.

    (aber von der Größe und Belegung sieht es ganz danach aus, als ob du den Fehler auf eine einzige Funktion einschränken kannst, die sehr oft in Schleife ausgeführt wird)



  • Hallo

    Ind der ProgrammNameDlg.cpp steht bereits:

    #ifdef _DEBUG
    #define new DEBUG_NEW
    #endif
    

    Was bringt das eigentlich?

    chrische



  • Das ersetzt das 'new' im Programmtext durch 'DEBUG_NEW' (und das führt wiederum zur Verwendung des 'operator new(size_t,char*,int)', der die Datei und Zeile aller new-Aufrufe mitprotokolliert. Setz mal dieses #define in die stdafx.h, damit diese Änderung vom GESAMTEN Programm übernommen wird.



  • Hallo

    Wenn ich das mache, bekomme ich sehr viele Fehlermeldungen. Unter anderem:

    error C2833: 'operator DEBUG_NEW' is not a recognized operator or type

    chrische


  • Mod

    Dann hast Du kein MFC Programm oder afx.h wurde nicht inkludiert!

    BTW:
    Die Ziffer in der geschweiften Klammer gibt die Allokationsnummer an. D.h. die wievielte Allokation es war.
    Wenn die Debug Ausgabe immer ziemlich ähnlich ist. Also Deine Allokationen immer so um die 2700 als Leak gemeldet werden, dann kannst Du mit

    _CrtSetBreakAlloc(2700);
    

    bei Programmstart das Programm bei der 2700 Allokation in den Debugger breaken lassen.
    Dann schaust Du Dir den Stacktrace an und wirst weise... 🕶



  • Hallo

    Es scheint an diesen Funktionen zu liegen. Da ich aber nicht weiß, wo hier der Fehler sein soll, lasse ich mal die Hosen runter und zeige meinen Code. Ich hoffe, dass er nicht allzu verfrickelt ist:

    bool chrische::Data::LoadCountriesFromFiles()
    {
    	chrische::EditorCountry Temp;
    	CString FileName;
    	CString Count;
    	CStdioFile FileToReadOut;
    	CString TempString;
    	for(int i=0; i<chrische::GetIni()->GetInt(_T("Load"), _T("CountCountries"), 0); ++i)
    	{
    		FileName = chrische::GetIni()->GetString(_T("Directories"), _T("CountryDirectory"));
    		Count.Format(_T("%d"), i+1);
    		FileName +=  _T("01")+ Count + _T(".cou");
    		FileToReadOut.Open(FileName, CStdioFile::modeRead);
    		if(!FileToReadOut)
    			return false;
    		else
    		{
    			FileToReadOut.ReadString(TempString);
    			Temp.SetName(TempString);
    			FileToReadOut.ReadString(TempString);
    			Temp.SetNationalAssociation(TempString);
    			FileToReadOut.ReadString(TempString);
    			Temp.SetInternationalAssociation(_wtoi(TempString.GetBuffer()));
    			FileToReadOut.ReadString(TempString);
    			Temp.SetID(TempString);
    			Countries.Add(Temp);
    		}
    		FileToReadOut.Close();
    	}
    	return true;
    }
    
    bool chrische::Data::LoadLeaguesFromFiles()
    {
    	CString Count;
    	CString Te;
    	CStdioFile FileToReadOut;
    	CString FileName;
    	chrische::EditorLeague Temp;
    	for(int i=0; i<chrische::GetIni()->GetInt(_T("Load"), _T("CountLeagues"), 0); ++i)
    	{
    		FileName = chrische::GetIni()->GetString(_T("Directories"), _T("LeaguesDirectory"));
    		Count.Format(_T("%d"), i+1);
    		FileName +=  _T("02")+ Count + _T(".lea");
    		FileToReadOut.Open(FileName, CStdioFile::modeRead);
    		if(!FileToReadOut)
    			return false;
    		else
    		{
    			FileToReadOut.ReadString(Te);
    			Temp.SetName(Te);
    			FileToReadOut.ReadString(Te);
    			Temp.SetParentCountry(Te);
    			FileToReadOut.ReadString(Te);
    			Temp.SetID(Te);
    			FileToReadOut.ReadString(Te);
    			Temp.SetNumberOfUpTeams(_wtoi(Te.GetBuffer()));
    			FileToReadOut.ReadString(Te);
    			Temp.SetNumberOfDownTeams(_wtoi(Te.GetBuffer()));
    			FileToReadOut.ReadString(Te);
    			Temp.SetNumberOfTeams(_wtoi(Te.GetBuffer()));
    			FileToReadOut.ReadString(Te);
    			Temp.SetPriority(_wtoi(Te.GetBuffer()));
    			AllLeagues.Add(Temp);
    		}
    		FileToReadOut.Close();
    	}
    	return true;	
    }
    
    bool chrische::Data::LoadCountryNamesFromFile()
    {
    	CStdioFile FileToReadOut;
    	FileToReadOut.Open(chrische::GetIni()->GetString(_T("Directories"), _T("CountryNamesDirectory")) + chrische::GetIni()->GetString(_T("FileNames"), _T("CountryNamesFileName")),  CStdioFile::modeRead);
    	if(FileToReadOut)
    	{
    		CString Temp;
    		while(FileToReadOut.GetPosition() != FileToReadOut.GetLength())
    		{
    			FileToReadOut.ReadString(Temp);
    			AllCountryNames.Add(Temp);
    		}
    		return true;
    	}
    	else
    		return false;
    }
    
    bool chrische::Data::LoadPlayerNamesFromFile()
    {
    	CStdioFile FileToReadOut;
    	FileToReadOut.Open(chrische::GetIni()->GetString(_T("Directories"), _T("PlayerNamesDirectory")) + chrische::GetIni()->GetString(_T("FileNames"), _T("PlayerNamesFileName")), CStdioFile::modeRead);
    	if(FileToReadOut)
    	{
    		CString Temp;
    		while(FileToReadOut.ReadString(Temp))
    		{
    			PlayerNames.Add(Temp);
    		}
    		return true;
    		FileToReadOut.Close();
    	}
    	else
    		return false;
    }
    
    bool chrische::Data::LoadPlayerSurNamesFromFile()
    {
    	CStdioFile FileToReadOut;
    	FileToReadOut.Open(chrische::GetIni()->GetString(_T("Directories"), _T("PlayerSurnamesDirectory")) + chrische::GetIni()->GetString(_T("FileNames"), _T("PlayerSurnamesFileName")), CStdioFile::modeRead);
    	if(FileToReadOut)
    	{
    		CString Temp;
    		while(FileToReadOut.ReadString(Temp))
    		{
    			PlayerSurNames.Add(Temp);
    		}
    		return true;
    		FileToReadOut.Close();
    	}
    	else
    		return false;
    }
    
    bool chrische::Data::LoadCoachesFromFile()
    {
    	CStdioFile FileToReadOut;
    	CString FileName;
    	CString Count;
    	CString TempString;
    	chrische::EditorCoach TempCoach;
    	for(int i=0; i<chrische::GetIni()->GetInt(_T("Load"), _T("CountCoaches"), 0); ++i)
    	{
    		FileName = chrische::GetIni()->GetString(_T("Directories"), _T("CoachDirectory"));
    		Count.Format(_T("%d"), i+1);
    		FileName += _T("05") + Count + _T(".coa");
    		FileToReadOut.Open(FileName, CStdioFile::modeRead);
    		if(!FileToReadOut)
    			return false;
    		else
    		{
    			FileToReadOut.ReadString(TempString);
    			TempCoach.SetName(TempString);
    			FileToReadOut.ReadString(TempString);
    			TempCoach.SetSurName(TempString);
    			FileToReadOut.ReadString(TempString);
    			TempCoach.SetStrength(_wtoi(TempString.GetBuffer()));
    			FileToReadOut.ReadString(TempString);
    			TempCoach.SetType(_wtoi(TempString.GetBuffer()));
    			FileToReadOut.ReadString(TempString);
    			TempCoach.SetFamilyStatus(_wtoi(TempString.GetBuffer()));
    			FileToReadOut.ReadString(TempString);
    			TempCoach.SetNationality(TempString);
    			FileToReadOut.ReadString(TempString);
    			TempCoach.SetBirthYear(_wtoi(TempString.GetBuffer()));
    			FileToReadOut.ReadString(TempString);
    			TempCoach.SetID(TempString);
    			FileToReadOut.ReadString(TempString);
    			TempCoach.SetIsInJob(_wtoi(TempString.GetBuffer()));
    			AllCoaches.Add(TempCoach);
    		}
    		FileToReadOut.Close();
    	}
    	return true;
    }
    

    Die Klasse Data ist ein Singleton. Vieleicht hängt es ja damit zusammen.

    Vielen Dank

    chrische



  • Hallo

    Ich wollte nun Erfolg vermelden. Ich habe nun noch einmal intensiv gesucht und den visual leak detector von codeproject.com zur Hilfe gebeten und gemerkt, dass ich vergessen hatte die Singleton auch wieder zu löschen.

    Danek für die Hilfe

    chrische



  • Was soll denn das Gehampel mit GetBuffer?



  • Hallo

    Ich dachte, dass das nur so geht und werde es aber jetzt gleich ändern.

    chrische


  • Mod

    GetBuffer kann nichts damit zu tun haben. In diesem Bereich sehe ich kein Leak.
    Hier wird weder new, noch malloc verwendet. Die Strings sind alle sicher, selbst wenn GetBuffer verwendet wird.

    Ich tippe eher auf die Objekte in denen die CString's liegen, die nicht freigegeben werden. Aber das sehen wir nicht wie die angelegt und freigegeben werden!



  • Hallo

    @MartinRichter

    Das mit GetBuffer() hat natürlich nichts damit zu tun. Ich hatte bereits geschrieben, dass ich vergessen hat, das Singleton beim Beenden des Programmes zu löschen und da in diesem Singleton eine Menge Daten lagern, gab es diese Unmenge an Memory Leaks.

    Vielen Dank für eure Hilfe.

    chrische


Anmelden zum Antworten