Speicherverwaltung in GTK+
-
Hallo,
Wenn man mit "gtk_window_new" ein neuer Objekt anlegt, so wird das doch auf dem Heap allokiert.
Objekte auf dem Heap müssen aber C doch immer von selbst freigegeben werden.
In den ganzen Anleitungen scheint es aber kein entsprechendes free oder delete zu geben.
-
gtk__ schrieb:
Hallo,
Wenn man mit "gtk_window_new" ein neuer Objekt anlegt, so wird das doch auf dem Heap allokiert.
Objekte auf dem Heap müssen aber C doch immer von selbst freigegeben werden.
In den ganzen Anleitungen scheint es aber kein entsprechendes free oder delete zu geben.Der Free/Delete erfolgt beim Beenden des Programms. Hier ein ganz simples Beispiel:
#include <gtk/gtk.h> int main( int argc, char *argv[]) { GtkWidget *window; gtk_init(&argc, &argv); window = gtk_window_new(GTK_WINDOW_TOPLEVEL); gtk_window_set_title(GTK_WINDOW(window), "Destroy on X clicked"); gtk_window_set_default_size(GTK_WINDOW(window), 230, 150); gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER); gtk_widget_show(window); g_signal_connect_swapped(G_OBJECT(window), "destroy", G_CALLBACK(gtk_main_quit), NULL); gtk_main(); return 0; }
Hier siehst Du, dass mit dem "destroy" Signal (also Klick auf
"gtk_main_quit" aufgerufen wird. Es werden in GTK+ dann alle Ressourcen freigegeb und das Programm beendet. Du brauchst also keine "free" o.ä.
-
Ohne dass ich jetzt GTK kennen würde, aber das klingt schon einfach nur falsch. Beim Beenden wird eh der ganze Speicher freigegeben. Und wenn es GTK beim Beenden kann, dann muss es auch während der Laufzeit gehen. Wär doch hochgradig bescheuert, wenn es nicht gehen würde.
-
KuhTee schrieb:
Ohne dass ich jetzt GTK kennen würde, aber das klingt schon einfach nur falsch. Beim Beenden wird eh der ganze Speicher freigegeben. Und wenn es GTK beim Beenden kann, dann muss es auch während der Laufzeit gehen. Wär doch hochgradig bescheuert, wenn es nicht gehen würde.
Wer lesen kann ist klar im Vorteil...
Wenn man mit "gtk_window_new" ein neuer Objekt anlegt, so wird das doch auf dem Heap allokiert.
Das war die Frage des TE... oder??
Ich vermute, das der TE aus der objektorientierten Welt kommt und daher eine solche Frage stellt.
Zunächst wird mit "gtk_window_new" kein neues "Objekt" angelegt. Was dort angelegt wird, sind Definitionen, die zu einem anzuzeigenden Fenster erzeugt werden sollen....
Ich begreife, dass mit GTK+ objektorientierte Ansätze etwas verloren gehen - aber dazu gibt es ja GTKmm (mm steht für -- und nicht etwa für ++)
Soweit so gut... Abgesehen davon, wenn man das Beispiel betrachtet, das ich postete, was will man dann noch "free"s machen. Fenster anzeigen - Ende - und gut ist.. - oder??
Die Frage stellt sich natürlich bei Parent Windows... Aber das war nicht die Frage des TE "T hread E röffners"Greez
-
Hallo,
Ich komme, wie schon richtig festgestellt von C++.
Mein Frage, war es wie die Objekte wieder gelöscht werden.
Dass man das Objekt bei einem einfachen "Hallo Welt!"-Fenster nicht explizit löschen muss ist mir klar, aber was passiert, wenn man mit gtk_window_new ein Fenster erzeugen will, das einem Konfigurationsmöglichkeiten gibt, oder eine Warn/Fehlermeldung ausgibt. Wenn ich ein Fenster(oder ein anderes Widget) nur mit gtk_window_new erzeuge. So müsste ich doch eigentlich ein Speicherleek haben.
Oder werden die Objekte nicht auf dem Heap sondern dem Stack angelegt?MfG.
-
-
Ok,
Danke.
-
abcdefg schrieb:
Ich vermute, das der TE aus der objektorientierten Welt kommt und daher eine solche Frage stellt.
Was hat das mit "objektorientiert" zu tun? Nix?
Speicher den ich anfordere muss ich auch wieder freigeben. Das ist auch in purem C so.
-
KuhTee schrieb:
Was hat das mit "objektorientiert" zu tun? Nix?
Speicher den ich anfordere muss ich auch wieder freigeben. Das ist auch in purem C so.Das ist richtig.
Hier geht es aber um ein Framework, das diverse Aufaben bezüglich Speicherverwaltung übernimmt. Wenn Du schreibst:
[...] Ohne dass ich jetzt GTK kennen würde [...]
würde ich mich einfach nicht in dieses Thema einmischen. Es ist z.B. durchaus üblich, dass man statt
gtk_widget_destroy
auch
gtk_widget_hide
(also verstecken des betroffenen Fensters, ohne es zu löschen oder den Speicher freizugeben) benutzt. Ich fühle mich hier aber absolut nicht berufen bei jeder GTK+ oder sonstigen Frage ein ganzes Tutorial zum Thema zu schreiben, sondern versuche auf den Fragesteller einzugehen - im übrigen mache ich das freiwillig und unendgeldlich.
Du kannst jetzt weiter kritisieren wie Du willst - aber dann bist Du wahrscheinlich eher ein Troll....Greez
-
Sorry wenn ich mich einmisch ...
Ich kenn mich mit GTK auch ned aus ...
Aber prinzipiell, als C/C++ Entwickler bekommt man in den Kopf gemeisselt, das was man an Ressourcen aquiriert, muss man auch wieder freigeben. Das ist auch einer der Punkte, die uns von anderen Programmierern unterschiedet, also fast unser markenzeichen.
Es gibt also nicht unbedingt niedrige Hemmschwelle, jemanden der meint "freigeben ??? ach brauchst du nicht" irgendwie zu glauben ^^ Das sollte uns naturbedingt sehr schwerfallen (wenn nicht, sollte man nen wechsel ins Garbage Collector Lager erwähnen).
Besser wer es, das Konzept zu erklären ... denn erst wenn wir das verstehen, hören wir auf das zu hinterfragen ^^, und können anfangen, kompatiblen Code zu schreiben ^^(Ich kenn einige Analogien aus der Qt. Da gibts auch ähnliches, und man muss verstehen, wie das Konzept mit den QObjects und dem autodelete funktioniert).
Und ich glaub nicht, das es ein gutes Konzept ist, die ressourcen in den Auto-Aufräum-mechanismus des Betriebssystems laufen zu lassen !?
Ich verwend z.b. Tools, die die ressourcen ueberwachen, die wuerden bei sowas (berechtigt) anschlagen ...Der Verweis auf gtk_widget_destroy() war schon besser
Soviel ich mittlerweile von GTK verstanden habe, koennen wir aber mit dir disskutieren, ob in deinem Beispiel ein
gtk_main(); /// Hinzugefuegt ! gtk_widget_destroy(window); return 0;
nicht besser wär !
Oder wird das window von der GTK doch geloescht ???
Wenn nicht:
Einig sind wir uns, das es keine Auswirkung auf das Laufzeitverhalten hat, der Heap wird von jedem ordentlichen OS bei Programmende wieder aufgerauemt.
Aber ist es guter Stil ???
Ich wuerd sagen nein ! Generell ists ne Schlechte Idee den Heap bei Programmaustritt unaufgerauemt zu lassen ....
Allein scho wegens der Memory Leak detection tools ...So jetzt wieder Du ...
Ciao ...
-
ok, hab mal kurz gegoogelt zu dem thema.
Was mich dann doch bissi beunruhigt:
- kein tutorial macht das gtk_widget_destroy(window) ....
- einige user haben Probleme mit gtk und memory leak detections.
- als "workaround" wird das gtk_widget_destroy am Ende aufgefuehrt, aber das wuerde die Probleme nicht beseitigen, sondern nur lindern ...
- gtk_init aquiriert auch Speicher, gibt ihn aber niemals frei.
- einmalig (also nicht in einer loop !?) aquirierter und nicht wieder freigegebener Speicher wird im gtk forum nicht als Memory leak angesehen !?(ja sie lassen das aufräumen der letzten Reste wirklich dem execution handler des BS)
- es gab mal ne gtk_exit funktion, laut definition sollte die allen von der gtk allokierten Speicher wieder freigeben ... ob sie es getan hat, keine Ahnung. Aber mittlererweile ist sie als depricated(bitte nicht mehr verwenden) markiert.Scheinbar scheint gtk und memory handling kein so einfaches und eindeutiges Thema zu sein wie wir c/c++ User es vielleicht gern hätten ...
Ich hab wirklich (noch) nix mit der gtk zu tun, aber intressiert hats mich trotzdem. Und ja wieder was dazugelernt, worüber ich in dem fall ned wirklich gluecklich bin (selbst qt, mfc und co schaffen es sich vor dem exit sauber ausm Heap zu raeumen)
Ciao ...
-
RHBaum schrieb:
ok, hab mal kurz gegoogelt zu dem thema.
Was mich dann doch bissi beunruhigt:
- kein tutorial macht das gtk_widget_destroy(window) ....
Genau das war es, was mich verunsichert hat.
- einige user haben Probleme mit gtk und memory leak detections.
- als "workaround" wird das gtk_widget_destroy am Ende aufgefuehrt, aber das wuerde die Probleme nicht beseitigen, sondern nur lindern ...Nur mal als Frage, wo genau hast du das gefunden? Würd' mich mal interessieren.
- gtk_init aquiriert auch Speicher, gibt ihn aber niemals frei.
- einmalig (also nicht in einer loop !?) aquirierter und nicht wieder freigegebener Speicher wird im gtk forum nicht als Memory leak angesehen !?(ja sie lassen das aufräumen der letzten Reste wirklich dem execution handler des BS)
- es gab mal ne gtk_exit funktion, laut definition sollte die allen von der gtk allokierten Speicher wieder freigeben ... ob sie es getan hat, keine Ahnung. Aber mittlererweile ist sie als depricated(bitte nicht mehr verwenden) markiert.Scheinbar scheint gtk und memory handling kein so einfaches und eindeutiges Thema zu sein wie wir c/c++ User es vielleicht gern hätten ...
Irgendwie, hab ich so langsam das Gefühl, dass sich die GTK-Jungs( und Mädels) sich nicht richtig Gedanken um die Speicherverwaltung gemacht haben.
Vielleicht sollte ich mich doch besser, nach einer anderen GUI Lib umsehen...MfG
-
gtk__ schrieb:
Irgendwie, hab ich so langsam das Gefühl, dass sich die GTK-Jungs( und Mädels) sich nicht richtig Gedanken um die Speicherverwaltung gemacht haben.
Vielleicht sollte ich mich doch besser, nach einer anderen GUI Lib umsehen...Ich habe gerade einen Test gemacht und in das Beispielprogramm nach dem gtk_main() einen destroy eingebaut:
#include <gtk/gtk.h> int main( int argc, char *argv[]) { GtkWidget *window; gtk_init(&argc, &argv); window = gtk_window_new(GTK_WINDOW_TOPLEVEL); gtk_window_set_title(GTK_WINDOW(window), "Destroy on X clicked"); gtk_window_set_default_size(GTK_WINDOW(window), 230, 150); gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER); gtk_widget_show(window); g_signal_connect_swapped(G_OBJECT(window), "destroy", G_CALLBACK(gtk_main_quit), NULL); gtk_main(); // // Hier gehts nach gtk_main_quit() weiter // gtk_widget_destroy(window); // return 0; }
Die Statements nach dem gtk_main() werden aufgerufen, wenn die Applikation einen gtk_main_quit() absetzt, sei es manuell oder durch ein Callback initiiert. Das Programm lässt sich natürlich fehlerfrei umwandeln, bei der Ausführung gibt es beim Beenden einen:
Gtk-CRITICAL **: gtk_widget_destroy: assertion `GTK_IS_WIDGET (widget)' failed
Das heisst für mich, dass die gtk_main_quit() das Aufräumen übernimmt und nicht das OS..
Aus diesem Grund kann man IMO auch bedenkenlos für weitere Fenster innerhalb eines Dialogs ein Fenster mit "gtk_widget_hide" verstecken und bei Bedarf ohne das Fenster neu erstellen zu müssen mit "gtk_widget_show" wieder anzeigen. Es gibt Dialog Fenster, bei denen ich IMMER einen gtk_widget_destroy() absetze, das sind z.B. Messagefenster.
Das Thema ist aber vielfältiger... Die GLib, die ja Grundlage für GTK+ ist, bietet vielfältige eigene Methoden, um die Speicherverwaltung zu managen. Etwa:g_slice_new() und g_slice_free()
Aber das ist ein anderes Thema. Wie bei jedem Framework ist am Anfang natürlich die Lernkurve steil....
Greez
-
Tja, würden die Jungs und Mädels um Gnome und GTK+ einfach auf C++ setzen, könnten die sich das Gefrickel sparen. Die bauen das in C nach, was C++ von Haus aus hat.
-
Artchi schrieb:
Tja, würden die Jungs und Mädels um Gnome und GTK+ einfach auf C++ setzen, könnten die sich das Gefrickel sparen. Die bauen das in C nach, was C++ von Haus aus hat.
Ja und Nein!
<offtopic>Sicher versuchen die GTK+ Leute einen objektorientierten Ansatz, der in meinen Augen auch bescheuert ist (objektorientiert ist in meinen Augen sowieso bescheuert)....
Was soll das innerhalb einer Klasse Methoden aufzurufen???Im obigen Beispiel würde es völlig ausreichen, eine Funktion, etwa "create_window" zu haben und dieser Funktion einen gewünschten Funktionscode beim Aufruf mit auf den Weg zu geben. Oder noch besser: ich versorge in meinem Programm die entsprechenden Variablen mit den gewünschten Werten und rufe dann die Funktion auf, die mir das Fenster erstellt.
Hier hätte ich einen erheblich geringeren - aber transparenteren - Programmieraufwand. Das Argument mit den globalen, statischen und sonstwie fehleranfälligen Variablen ist absolut Unix und Windows "hausgemacht", da der Ansatz vollkommen falsch ist. Ich progge seit über 27 Jahren - vorwiegend im Mainframe Bereich - dort stellt sich das Problem mit ungewollter Veränderung von Variablen nicht, da das konzeptionelle Design schlicht sauberer ist...
Ach ja - zurück zu C: hier finde ich wenigstens ansatzweise eine gewisse konzeptionelle Sauberkeit - aber eben nicht besonders perfekt... daher wurde C++ entwickelt und das ist IMO noch bescheuerter... sorry
</offtopic>
-
Ich meinte nicht den OO-Ansatz! Sondern die Resourcen-Verwaltung. In C++ habe ich Konstruktoren und Destruktoren, in Kombination mit autom. Stack-Bereinigung hat man RAII. Alles von Haus aus. Aber in C müssen die Jungs halt Fleissarbeit leisten und schwitzen noch das alles gut geht.
-
Tja, würden die Jungs und Mädels um Gnome und GTK+ einfach auf C++ setzen, könnten die sich das Gefrickel sparen. Die bauen das in C nach, was C++ von Haus aus hat.
vergiss nicht, das C auch Vorteile hat ... das ABI, was C++ leider noch abgeht :-(. Nicht jedes OS hat einen "Systemcompiler".
Und ja, C ist da bissi eklig was Speicherverwaltung angeht. Um Komfort reinzubringen muss man da ja scho ganz schoen klimmzüge machen. Ich arbeit grad bissi mit der APR ... das fühlt sich so ganz anders an ^^ wie autofahren ohne schwerkraft ^^
Nur mal als Frage, wo genau hast du das gefunden? Würd' mich mal interessieren
.
http://mail.gnome.org/archives/gtk-list/2008-September/msg00099.html
manchmal ganz intressant sowas zu verfolgen, gibts noch zig DInge ...
http://ubuntuforums.org/showthread.php?t=1287827
http://www.mail-archive.com/gtk-list@redhat.com/msg00414.htmlCiao ....