000
08.09.2006, 12:08 Uhr
AndyDD
|
Hallo,
ich habe ein Verständnisproblem mit dem Anlegen von Zeigern auf dem Heap. Kurz zur Aufgabenstellung: ich arbeite bei der Darstellung meiner Animation in der Offscreentechnik. Auf dem Bildschirm sollen Messwerte grafisch dargestellt werden. Ein Thread bedient die Messkarte und schreibt Messwerte in Variablen der Doc-Klasse. Dort werden auch die darzustellenden Bildpunkte errechnet. Somit ist die Kapselung dieses Threads gewährleistet. Ich habe dazu in meiner Doc-Klasse zwei Membervariablen definiert:
C++: |
CBitmap* m_pBitmap CBitmap* m_pBitmapCopy
|
Es werden immer zwei benötigt, da die Copy einzig und allein dazu da ist, von der View-Klasse die Darstellung und somit den Zugriff zu realisieren, während der Workerthread bereits wieder Bildpunkte berechnet und in die andere Bitmap reinschreibt.
Im Konstruktor meiner Doc-Klasse wird folgender Code aufgerufen:
C++: |
void CMyAppDoc::Erstelle_Bitmap(void) { CDC memDC; memDC.CreateCompatibleDC (NULL); CBitmap *pOldBitmap;
COLORREF rgbColor;
m_pBitmap = new CBitmap (); m_pBitmap->CreateBitmap (kViewSize_x, kViewSize_y, 1, memDC.GetDeviceCaps (BITSPIXEL), NULL); m_pBitmapCopy = new CBitmap (); m_pBitmapCopy->CreateBitmap (kViewSize_x, kViewSize_y, 1, memDC.GetDeviceCaps (BITSPIXEL), NULL);
// Initialisieren der Bitmap zur Berechnung pOldBitmap = memDC.SelectObject (m_pBitmap); // Schwarz memDC.PatBlt (0,0,kViewSize_x,kViewSize_y,BLACKNESS);
{ int Hintergrundmodus=GetBkMode(memDC); SetBkMode(memDC,TRANSPARENT); rgbColor = RGB(255,255,255); CPen Pen_solid(PS_SOLID, 0, rgbColor); CPen Pen_dash(PS_DOT, 0, rgbColor); CPen* oldPen; oldPen = memDC.SelectObject(&Pen_solid); memDC.MoveTo((kViewSize_x/2),0); memDC.LineTo((kViewSize_x/2),(kViewSize_y)); memDC.SelectObject(&Pen_dash); int Breite_Fadenkreuz=40; memDC.MoveTo(Mittelpunkt_links.x,(Mittelpunkt_links.y-Breite_Fadenkreuz/2)); memDC.LineTo(Mittelpunkt_links.x,(Mittelpunkt_links.y+Breite_Fadenkreuz/2)); memDC.MoveTo(Mittelpunkt_rechts.x,(Mittelpunkt_rechts.y-Breite_Fadenkreuz/2)); memDC.LineTo(Mittelpunkt_rechts.x,(Mittelpunkt_rechts.y+Breite_Fadenkreuz/2)); memDC.MoveTo((Mittelpunkt_links.x-Breite_Fadenkreuz/2),Mittelpunkt_links.y); memDC.LineTo((Mittelpunkt_links.x+Breite_Fadenkreuz/2),Mittelpunkt_links.y); memDC.MoveTo((Mittelpunkt_rechts.x-Breite_Fadenkreuz/2),Mittelpunkt_rechts.y); memDC.LineTo((Mittelpunkt_rechts.x+Breite_Fadenkreuz/2),Mittelpunkt_rechts.y); memDC.SelectObject(oldPen); SetBkMode(memDC,Hintergrundmodus); } // Aufräumen memDC.SelectObject (pOldBitmap); }
|
Zum Darstellen des Ganzen wird dann einfach in der OnDraw-Methode die Bitmap aus dem Speichergerätekontext auf den Bildschirm geblittet.
Das funktioniert auch soweit ganz gut. Problematisch wird das ganze, wenn ich einen neuen Messzyklus aufrufen möchte. Dazu lösche ich die beiden Bitmaps wie folgt:
C++: |
void CMyAppDoc::Loesche_Bitmap(void) { if (m_pBitmap) delete m_pBitmap; if (m_pBitmapCopy) delete m_pBitmapCopy; }
|
Der gleiche Code wird auch vom Destruktor der Doc-Klasse aufgerufen.
Jetzt das Problem: führe ich nur einen Messdurchgang aus funktioniert das Ganze wunderbar. Will der Nutzer einen neuen Messdurchgang durchführen (Klick auf einen Button) und überlegt es sich dann aber doch anders und beendet das Programm bekomme ich eine unbehandelte Ausnahme an der Stelle delete m_pBitmap. In diesem Falle wird diese Löschfunktion zweimal hintereinander aufgerufen. Die Prüfung, ob die Membervariable einen gültigen Zeiger auf ein CBitmap-Object hat, scheint hier positiv zu sein obwohl ich doch beim vorherigen Durchlauf den Zeiger mit delete freigegeben habe. Wo liegt hier der Fehler? Dieses Problem taucht nicht auf wenn ich lösche und mit new eine neue Bitmap anlege... |