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 variable
    

    es 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 zeichnen

    void 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ß).


Anmelden zum Antworten