Code erzeugt speicherleck *frust*
-
moin,
ich bin grad dabei ein programm zu schreiben, leider erzeugt der code anscheinend ein speicherleck, obwohl ich alle temporären variablen lösche, bzw. versuche zu löschen.
Bei dem Programm handelt sich um ein Objektbasierendem Zeichenprogramm, mit etwas anderen ansprüchen als an Beispielsweise MSPaint. Die einzelnen Objekte werden in einem CObArray gespeichert.
Den Folgenden Code rufe ich beim Zeichnen einen neues Objektes, bzw. beim Neu Zeichnen des Fensters auf.
[edit]als anmerkung, das programm ist dialogfeld-basierend und ich verwende visual c++ 6.0[/edit]void CSkizzenIIDlg::ZeichneObjektNr(int iNr) { CClientDC dc(this); CObjekte* Objekt = new CObjekte(); //eine von CObject abgeleitet Klasse Objekt = (CObjekte*) m_coaObjekte.GetAt(iNr);; //eine CObArray variable //Brush CBrush brush; //Farbe[0] = Vordergrund; Farbe[1] = Hintergrund //Farbe[x][0] = Rot; Farbe[x][1] = Grün; Farbe[x][2] = Blau brush.CreateHatchBrush(HS_DIAGCROSS, RGB(Objekt->m_bFarbe[0][0], Objekt->m_bFarbe[0][1], Objekt->m_bFarbe[0][2])); //Pen CPen pen; pen.CreatePen(PS_DOT, 1, RGB(Objekt->m_bFarbe[0][0], Objekt->m_bFarbe[0][1], Objekt->m_bFarbe[0][2])); dc.SelectObject(&pen); //2. Farbe (Hintergrund) dc.SetBkColor(RGB(Objekt->m_bFarbe[1][0], Objekt->m_bFarbe[1][1], Objekt->m_bFarbe[1][2])); CRect rect; rect.left = Objekt->m_iKoords[0]; //Koords[0] = x-Achse; Koords[1] = y-Achse rect.right = Objekt->m_iKoords[0] + Objekt->m_iGroesse[0]; rect.top = Objekt->m_iKoords[1]; rect.bottom = Objekt->m_iKoords[1] + Objekt->m_iGroesse[1]; switch(Objekt->m_iTyp) //m_iTyp gibt an ob Linie, Rechteck... gezeichnet werden soll { case 0: //Linie (gestrichelt) dc.MoveTo(rect.left, rect.top); dc.LineTo(rect.right, rect.bottom); break; case 1: //Rechteck (gemustert) dc.FillRect(rect, &brush); break; case 2: //Ellipse dc.SelectObject(&brush); dc.Ellipse(rect); break; case 3: //Rahmen (Rechteck) dc.FrameRect(rect, &brush); break; } //Temporäre Objekte löschen pen.DeleteObject(); brush.DeleteObject(); dc.DeleteTempMap(); //dc.DeleteDC führt zum Absturz des Programmes }Danke im Voraus
-
Emperor_L0ser schrieb:
CObjekte* Objekt = new CObjekte(); //eine von CObject abgeleitet Klasse }Du musst nacher noch "delete Objekt;" aufrufen.
Grüße Rapha
-
Hallo,
da stimmt mehreres nicht.
Rapha hat schon recht, aber das eigentliche Problem ist das hier:
CObjekte* Objekt = new CObjekte(); //eine von CObject abgeleitet Klasse Objekt = (CObjekte*) m_coaObjekte.GetAt(iNr);; //eine CObArray variablees bewirkt, daß Speicher mit new angefordert wird, aber der sofort in der "Luft hängt", wenn Objekt danach sowieso ein Objekt-Zeiger aus dem CObArray zugewiesen wird.
Desweiteren: es ist verboten, noch in den Gerätekontext eingesetzte GDI-Objekte mit DeleteObject zu löschen:
pen.DeleteObject(); brush.DeleteObject();MSDN schrieb:
An application should not call DeleteObject on a CGdiObject object that is currently selected into a device context.
der CPen und der CBrush werden schon vom Destruktor ordentlich entsorgt, so daß keinerlei Löschen nötig ist.
Außerdem sollten die vorher in den Gerätekontext eingesetzten Objekte beim Einsetzen der neuen gesichert und vor dem Verlassen der Funktion wieder eingesetzt werden
MfG
-
hmm.. ich habe meinen code jetzt wie folgt geändert
CClientDC dc(this); CObjekte* Objekt; // = new CObjekte(); //eine von CObject abgeleitet Klasse Objekt = (CObjekte*) m_coaObjekte.GetAt(iNr);; //eine CObArray variable /* * und */ //Temporäre Objekte löschen //pen.DeleteObject(); //brush.DeleteObject(); //dc.DeleteTempMap(); //dc.DeleteDC führt zum Absturz des Programmes delete Objekt;Das mit dem speicher anfordern stimmt ja auch...

es funktioniert auch, so lange ich nur ein neues objekt hinzufüge, wenn ich jedoch alles neu zeichnen (z.b. bei größenänderung des fensters) stürzt mein programm ab.
mit folgendem code lasse ich alle objekte neu zeichnenvoid CSkizzenIIDlg::ZeichneObjekte() { if(m_coaObjekte.GetSize() > 0) { for(int i = 0; i < m_coaObjekte.GetSize(); i++) { ZeichneObjektNr(i); } } }ist also nichts weiter dran.
kann es sein, da 'CObjekt* Objekt;' nur ein zeiger ist, dass ich mit delete Objekt jedesmal ein teil meines Arrays lösche?Probe-Nutzer schrieb:
Außerdem sollten die vorher in den Gerätekontext eingesetzten Objekte beim Einsetzen der neuen gesichert und vor dem Verlassen der Funktion wieder eingesetzt werden
den teil versteh ich vom sinn her nicht, was soll wo gesichert werden? O.o
-
Emperor_L0ser schrieb:
den teil versteh ich vom sinn her nicht, was soll wo gesichert werden? O.o
Der Rückgabewert von SelectObject, denn dieser repräsentiert das alte selektierte Objekt. Dann kannst du später dieses Objekt wieder selektieren (blöder Außdruck ich weiß).