Speicherleck
-
Ich habe irgendwo in meinem Code ein Speicherleck, kann es aber nicht finden.
Meine GDI Objekte vermehren sich...
was ist daran falsch?void CCanvas::Line(int x1,int y1, int x2,int y2) { HPEN hPen; hPen = CreatePen(0,0,PenColor); m_pDC->SelectObject(hPen); m_pDC->MoveTo(x0+x1,y0+y1); m_pDC->LineTo(x0+x2,y0+y2); m_pDC->DeleteTempMap(); DeleteObject(hPen); }so wird die funktion aufgerufen:
void CPlainXYDialog::OnMouseMove(UINT nFlags, CPoint point)
{if ((nFlags & MK_LBUTTON) == MK_LBUTTON)
{
Canvas.m_pDC = this->GetDC();
Canvas.PenColor = m_pDoc->Image3D.ColorPalette.CurrentColor;
if (m_ptLastCursorClickPosition.x !=0)Canvas.Line(m_ptLastCursorClickPosition,point);
Canvas.m_pDC->DeleteTempMap();}
m_ptLastCursorPosition2 = m_ptLastCursorPosition;
m_ptLastCursorPosition = point;CDialog::OnMouseMove(nFlags, point);
}
-
Wenn man ein Objekt mit SelectObject in einen Gerätekontext selektiert, wird das Objekt, das zuvor selektiert war, zurückgegeben. Nimm noch eine Variable, die z.B. hOldPen heißt, und speichere das alte Pen. Am Ende deiner Zeichenoperationen selektierst du das alte Pen wieder in den Gerätekontext, damit wirklich alle Ressourcen wieder freigegeben werden. So sollte es zumindest sein.
Aber: Obwohl ich das bei meinem Programm nicht mache (weil es noch im Alpha-Status ist), vermehren sich die GDI Objekte nicht...Irgendwie eigenartig.
-
Ich vermute mal das ganze da is nen Wrapper und nutzt unter anderem SelectObject()
[cpp]
SelectObject()
This function returns the previously selected object of the specified type. An application should always replace a new object with the original, default object after it has finished drawing with the new object.
[/cpp]
Du solltest den Rückgabewert (was quasi der alte PEN ist) speichern und bevor du deinen neuen Pen mit DeleteObject() löscht den alten Pen wieder in den DeviceContext reinselektieren.
Ansonsten ist der alte Pen quasi im Speicher verloren......außerdem sagt die PSDK-Doku zu DeleteObject:
"Do not delete a drawing object (pen or brush) while it is still selected into a DC."
-
Danke, das Hauptproblem ist weg, ich hab jetzt nur noch kleinere Speicherlecks

-
Wenn ich einen kompatiblen Gerätekontext erstellt habe, dann hat der ja zu Beginn keine Bitmap drin, falls ich micht nicht täusche. In diesem Fall muss ich nicht das alte Objekt speichern, und später wieder zurückselektieren, oder? Aber wenn das der Fall ist, dann macht der Hinweis aus der MSDN Probleme; nämlich der, dass man keine Objekte löschen soll, die gerade im DC sind...
-
Achja, ich erinnere mich in einem Buch gelesen zu haben, dass in einem Memory DC (also kompatible DC's) zu Beginn ein monochromes Bitmap drinnen ist. Somit hab ich mir die Frage von vorhin selber beantwortet...
-
Hey Aziz,
http://www.c-plusplus.net/forum/posting.php?mode=editpost&p=70810nicht
http://www.c-plusplus.net/forum/posting.php?mode=reply&t=70810
:p
-
Hey, ich versuche die Anzahl meiner Postings zu erhöhen

-
Hab ich mir auch schon gedacht. :p
-
HGDIOBJ OldObj; OldObj=SelectObject(hdc, newObject); // bla :D DeleteObject( SelectObject(hdc, OldObj) );...kann nie schaden

Kewl - Smileys funzen sogar im Quellcode

-
Nur mal eine blöde Frage - wie stellt man denn Speicherlecks fest?

-
z.B. indem du im Taskmanager siehst, dass der Speicherverbrauch mit zunehmender Zeit immer weiter ansteigt

-
Im Taskmanager kannst du sogar sehen wieviele GDI-Objekte von den Programmen verwendet werden, die gerade laufen. Einfach im Menü auf Ansicht->Spalten gehen und dann bei der Checkbox "GDI-Objekte" ein Häkchen setzen.
Und logischerweise erhöht sich die Anzahl der verwendeten GDI-Objekte wenn dein Programm leakt...
-
Jep - sollte man eigentlich immer tun.