Lokale Variablen?
-
hallo zusammen,
einfach nehme ich die folgende Funktion, die von msdn ist,void DrawARectangle(HDC hdc) { HPEN hpen, hpenOld; HBRUSH hbrush, hbrushOld; // Create a red pen. hpen = CreatePen(PS_INSIDEFRAME, 13, RGB(255, 0, 0)); // Create a green brush. hbrush = CreateSolidBrush(RGB(0, 255, 0)); hpenOld = SelectObject(hdc, hpen); hbrushOld = (HBRUSH)SelectObject(hdc, hbrush); Rectangle(hdc, 100,100, 700,200); // Do not forget to clean up. SelectObject(hdc, hpenOld); DeleteObject(hpen); SelectObject(hdc, hbrushOld); DeleteObject(hbrush); }ich habe eine Frage:
ich glaube, die Variablen in Funktion sind lokale Variablen,
wenn ich bei Funktion-Verlassen diese Objekte nicht "clean up", bauen sie selber nicht ab?
-
Doch, normalerweise tun sie das.
Variablen, die in Funktionen erstellt werden, sind immer lokal zur Funktion, also außerhalb der Funktion nicht erkennbar (Ausnahme: Static-Variablen). Je nachdem, ob Deine Aufrufstandards stdcall oder cdecl sind, werden die Variablen von der aufrufenden oder aufgerufenen Funktion abgebaut- zumindest solche, die auf dem Stack liegen. Variablen, die nur im normalen Speicher angelegt werden, werden einfach ungültig, d. h. die Werte bleiben vorläufig im Speicher, aber der Speicher wird für den Zugriff durch andere Prozesse freigegeben.
-
damo schrieb:
ich glaube, die Variablen in Funktion sind lokale Variablen
Richtig.
damo schrieb:
wenn ich bei Funktion-Verlassen diese Objekte nicht "clean up", bauen sie selber nicht ab?
Nein, die Variablen verlieren ihre Gültigkeit und damit auch ihren lokal zugewiesenen Speicherplatz) beim Verlassen der Funktion.
Du mußt die Variablen somit nicht explizit löschen oder irgendwie aus dem Speicher entfernen.Das gleiche glit auch für in Funktionsaufruf übergebene Parameter-Variablen (hier in Deinem Beispiel HDC hdc), welche prinzipbedingt auch lokale Variablen sind.
Martin
-
ohje...
die aufräumarbeiten beziehen sich hier auf die variablen (pointer) als GDI-Objekte, die in jedem Fall freigegeben werden müssen, sonst kommts zu GDI-Leaks (etwas anderes als memory-leaks

-
Ooops, ja, stimmt. SelectObject-Objekte müssen freigegeben werden.

-
Die Frage bezog sich auf die lokale Fariablen, oder nicht?
Was Windows-Objekte betrifft, gilt generell: Alles was Du generierst (Fenster, Mutex, Controls, Fonts, HDC, ... ), mußt Du nach Gebrauch auch wieder freigeben.
Es gibt natürlich auch Ausnahmen, z.B. bei GetStockObject() mußt Du hinterher nicht freigeben.
Da hilft nur eines: Immer die MSDN-Dokumentation der jeweiligen Funktionen genau lesen. Oft steht dort auch ein Hinweis, durch welche (Gegen-)Funktion ein Objekt wieder freigegeben bzw. zerstört werden.
Übrigens, habe mir Dein Code genauer angesehen: Mir fällt auf, daß Du versuchst die alten Objekte hpenOld und hbrushOld wiederherszustellen. Dabei sind diese Variablen ja gar nicht mit sinnvollen Werten geladen (da hätte Dein Compiler aber Warnungen melden müssen).
Martin
-
@Elektronix & @Mmacher :
vielen Dank! das habe ich auch gemeint!@Xantus
hahhaaa, danke schön für Erinnerung! hab mich noch an die Code angeschaut, und dann jetzt hab richtig die Code verstanden.Früher hab ich einfach gedacht, dass die Funktion beschreibt: wähle ein new pen, dann lösche es. Aber ganz falsch!!! Die "clean up" new pen, und dann das alte pen zurückgesetzt!!!
nochmal EUCH alle vielen Dank. (die komplette Codes jetzt sind da)
-
damo schrieb:
@Elektronix & @Mmacher :
vielen Dank! das habe ich auch gemeint!@Xantus
hahhaaa, danke schön für Erinnerung! hab mich noch an die Code angeschaut, und dann jetzt hab richtig die Code verstanden.Früher hab ich einfach gedacht, dass die Funktion beschreibt: wähle ein new pen, dann lösche es. Aber ganz falsch!!! Die "clean up" new pen, und dann das alte pen zurückgesetzt!!!
nochmal EUCH alle vielen Dank. (die komplette Codes jetzt sind da)
Oha, kleine Frage am Rande: Soll das Deutsch sein?
Mmacher schrieb:
Alles was Du generierst (Fenster, Mutex, Controls, Fonts, HDC, ... ), mußt Du nach Gebrauch auch wieder freigeben.
Naja, Controls werden aber durch's Parent abgebaut
. Da musst Du nicht explizit DestroyWindow aufrufen. Aber sonst stimmt das natürlich.Mmacher schrieb:
Übrigens, habe mir Dein Code genauer angesehen: Mir fällt auf, daß Du versuchst die alten Objekte hpenOld und hbrushOld wiederherszustellen. Dabei sind diese Variablen ja gar nicht mit sinnvollen Werten geladen (da hätte Dein Compiler aber Warnungen melden müssen).
Doch der Code ist vollkommen korrekt. Er (bzw. der Code aus der MSDN
) setzt die alten Objekte, die sich im HDC befanden wieder ein. DAS und nur das ist korrektes Aufräumen (= CleanUp) (siehe Doku zu SelectObject)
. Außerdem werden die Variablen doch initialisiert, hier:hpenOld = SelectObject(hdc, hpen); hbrushOld = (HBRUSH)SelectObject(hdc, hbrush);
-
CodeFinder schrieb:
Doch der Code ist vollkommen korrekt. Er (bzw. der Code aus der MSDN
) setzt die alten Objekte, die sich im HDC befanden wieder ein. DAS und nur das ist korrektes Aufräumen (= CleanUp) (siehe Doku zu SelectObject)
. Außerdem werden die Variablen doch initialisiert, hier:hpenOld = SelectObject(hdc, hpen); hbrushOld = (HBRUSH)SelectObject(hdc, hbrush);Meine Feststellung sieht so gesehen natürlich total unsinnig aus.
Denn damo hat bei seinem ersten Post genau diese Zeilen weggelassen. Woraufhin er auf meine Feststellung hin, den Code im nachhinein korrigiert hat.
Jetzt ist der Code so wie er jetzt da steht natürlich in Ordnung.Martin
-
@CodeFinder:
du hast mir viel Mals geholfen, ich glaube, dass du schon weisst, dass mein Deutsch nicht gut ist.
was soll "die komplette Codes jetzt sind da" heissen?ganz ehrlich sagen: Deutschsprache ist schwieriger als Assemblersprache.