Hallo Liste Ich muß vorausschicken das ich gerade meine ersten Gehversuche mit Qt und C++ unter Suse Linux 9.3 mache. Die vorangegangene Diskusion (frage zu Objekten in c++) hat mir viel geholfen. Jetzt fehlt mir nur noch etwas zum richtigen Verständnis der Materie. In der Doku von QT unter QSqlCursor habe ich etwas gefunden was nicht richtig verstehe. (liegt wohl auch an meinen schlechten Englisch) Da steht das QT den Cursor nicht automatisch löscht sondern ich dafür verantwortlich bin. Ich stelle mir das jetzt einfach mal so vor: QSqlCursor *cursor = new QSqlCursor; delete cursor; (Hoffentlich stimmt das so) Aber selbst in den Beispielen von Qt finde ich immer nur sowas: QSqlCursor cur( "prices" ); Eigentlich habe ich gedacht das sich solche Variablen von selbst töten wenn die Funktion beendet wird. (Stimmt das?) (Wie ist das eigentlich mit Variablen die ich im Konstruktor definiere? Wann sterben die?) Die Frage ist nun wie ich einen QSqlCursor richtig töte? Und gibt es noch mehr solche Qt-Objekte die ich selber töten muss? Da ich immer wieder bei meinen Dialogen, die viel mit SQL arbeiten, das Problem habe das beim zweiten Start ein SegFault kommt wäre ich für etwas Hilfe sehr dankbar. -- Mit freundlichen Grüßen Ludwig Fromke
Hey, du sprichst genau mein grösstes Rätsel an. Wie arbeiten Profis mit C/C++ Bibliotheken? Ohne perfekte Doku kann man ja nie sagen, wann welches Objekt noch lebt, bzw. wie lange ein zurückgegebener Zeiger noch auf reservierten Speicher zeigt. Generell denke ich, dass es folgendermaßen ist: Alle "normalen" Variablen werden auf dem Stack angelegt und gelten exakt so lange wie die äusseren { } - Klammern darum sind. Gibt es da Ausnahmen? Alle new Speicherbereiche werden auf dem Heap angelegt und sind daher bis zum delete erreichbar (solange man nicht die Adresse verschlampt). Von daher ist Dein Cursor (ich hab keine Ahnung von QT) wenn er so deklariert wird: QSqlCursor cur( "prices" ); am Ende auch wieder tot. Automatisch. Was allerdings sein kann ist, dass das QSqlCursor Objekt Speicher allokiert, der nicht in dessen Destructor gelöscht wird. Warum das so ist und was es in Deinem Fall ist weiss ich nicht. Wegen dem Constructor: Lokale Variablen die im Constructor deklariert werden sind nach dem Constructor wieder weg. Um sie während der kompletten Existenz des Objekts zur Verfügung zu haben kommen die dann in die Klassendefinition. Im Konstruktor findet dann die Initialisierung dergleichen statt. Falls ich irgendwo quatsch erzähle bitte korrigieren. gruß Marcel Ludwig Fromke wrote:
Hallo Liste
Ich muß vorausschicken das ich gerade meine ersten Gehversuche mit Qt und C++ unter Suse Linux 9.3 mache. Die vorangegangene Diskusion (frage zu Objekten in c++) hat mir viel geholfen. Jetzt fehlt mir nur noch etwas zum richtigen Verständnis der Materie. In der Doku von QT unter QSqlCursor habe ich etwas gefunden was nicht richtig verstehe. (liegt wohl auch an meinen schlechten Englisch) Da steht das QT den Cursor nicht automatisch löscht sondern ich dafür verantwortlich bin. Ich stelle mir das jetzt einfach mal so vor: QSqlCursor *cursor = new QSqlCursor; delete cursor; (Hoffentlich stimmt das so)
Aber selbst in den Beispielen von Qt finde ich immer nur sowas: QSqlCursor cur( "prices" ); Eigentlich habe ich gedacht das sich solche Variablen von selbst töten wenn die Funktion beendet wird. (Stimmt das?) (Wie ist das eigentlich mit Variablen die ich im Konstruktor definiere? Wann sterben die?)
Die Frage ist nun wie ich einen QSqlCursor richtig töte? Und gibt es noch mehr solche Qt-Objekte die ich selber töten muss?
Da ich immer wieder bei meinen Dialogen, die viel mit SQL arbeiten, das Problem habe das beim zweiten Start ein SegFault kommt wäre ich für etwas Hilfe sehr dankbar.
Am Dienstag, 22. November 2005 15:45 begab es sich, daß adsci folgendes in den Rechenknecht kloppte:
Hey, du sprichst genau mein grösstes Rätsel an.
Wie arbeiten Profis mit C/C++ Bibliotheken? Ohne perfekte Doku kann man ja nie sagen, wann welches Objekt noch lebt, bzw. wie lange ein zurückgegebener Zeiger noch auf reservierten Speicher zeigt.
Generell denke ich, dass es folgendermaßen ist:
Alle "normalen" Variablen werden auf dem Stack angelegt und gelten exakt so lange wie die äusseren { } - Klammern darum sind. Gibt es da Ausnahmen?
Nein!
Alle new Speicherbereiche werden auf dem Heap angelegt und sind daher bis zum delete erreichbar (solange man nicht die Adresse verschlampt).
Von daher ist Dein Cursor (ich hab keine Ahnung von QT) wenn er so deklariert wird:
QSqlCursor cur( "prices" );
am Ende auch wieder tot. Automatisch. Was allerdings sein kann ist, dass das QSqlCursor Objekt Speicher allokiert, der nicht in dessen Destructor gelöscht wird. Warum das so ist und was es in Deinem Fall ist weiss ich nicht.
Die Qt-Klassen sind IMHO so gut optimiert, daß sie keine Leaks produzieren. Allerdings besagt die Qt-Doku, daß alle Objekte, die von QObject, also der Stammklasse dieser Bibliothek, abgeleitet sind, ihre Kind-Objekte (das wird bei der Initialisierung festgelegt) auch selber wieder tötet. Darauf muss man sich nicht verlassen, weil es erst nach meinem Destruktor passiert, und ich verlass mich auch nicht drauf. Denn QSqlCursor ist z.B. nicht von QObject abgeleitet, also gehört der spätestens im Destruktor der deklarierenden Klasse deleted. Noch'n Hinweis an Ludwig: 98 % der SegFaults, die bei mir auftreten, liegen darin begründet, daß ich zwar brav meinen Zeiger deklariere (der dann irgendwohin zeigt), ihn aber zu initialisieren vergesse, weil der Kontruktor ohne Parameter aufgerufen werden kann. Wenn dann hierauf schreibend oder ausführend zugreife...Peng!
Wegen dem Constructor: Lokale Variablen die im Constructor deklariert werden sind nach dem Constructor wieder weg. Um sie während der kompletten Existenz des Objekts zur Verfügung zu haben kommen die dann in die Klassendefinition. Im Konstruktor findet dann die Initialisierung dergleichen statt.
Falls ich irgendwo quatsch erzähle bitte korrigieren.
Nein, passt alles. Eine Bitte hätte ich allerdings an dich: http://learn.to/quote! TOFU ist grauenvoll zu lesen... ;-) -- --- Grüsse aus Meissen Jörg Pauly
Hallo, Am Tue, 22 Nov 2005, adsci schrieb:
Wie arbeiten Profis mit C/C++ Bibliotheken? Ohne perfekte Doku kann man ja nie sagen, wann welches Objekt noch lebt, bzw. wie lange ein zurückgegebener Zeiger noch auf reservierten Speicher zeigt.
Generell denke ich, dass es folgendermaßen ist:
Alle "normalen" Variablen werden auf dem Stack angelegt und gelten exakt so lange wie die äusseren { } - Klammern darum sind. Gibt es da Ausnahmen?
Ja. Mit 'static' deklarierte Variablen. Bsp.: ,----[ staticvar.cc ] | #include <cstdio> | | int foo(void) { | static int j = 0; | return ++j; | } | | int bar(void) { | int k = 0; | return ++k; | } | | int main(void) { | for( register int i = 0; i < 10; ++i ) { | printf("foo=%i, bar=%i\n", foo(), bar()); | } | return 0; | } `---- Note: Zumindest fuer sowas ziehe ich printf aus <cstdio> dem cout aus <iostream> deutlich vor... Aufgabe: fuehre obiges Beispiel jew. eine '{}'-Ebene "tiefer" und demonstriere dabei den Effekt der zusaetzlichen '{}'.
Falls ich irgendwo quatsch erzähle bitte korrigieren.
s.o.
Ludwig Fromke wrote:
Ich muß vorausschicken das ich gerade meine ersten Gehversuche mit Qt und C++ unter Suse Linux 9.3 mache. [..] In der Doku von QT unter QSqlCursor habe ich etwas gefunden was nicht richtig verstehe. (liegt wohl auch an meinen schlechten Englisch) Da steht das QT den Cursor nicht automatisch löscht sondern ich dafür verantwortlich bin. Ich stelle mir das jetzt einfach mal so vor: QSqlCursor *cursor = new QSqlCursor; delete cursor; (Hoffentlich stimmt das so)
Ja. Was du mit 'new' anlegst musst du mit 'delete' abraeumen. Deshalb sollten Variablen wenn moeglich "automatisch" und so lokal wie moeglich sein (wie das 'k' in bar() oben). Auch bei "Member"-Variablen von Objekten gilt das uebrigens. Gut ist es, wenn man die Variablen / Member im Konstruktur nur _initialisieren_, nicht aber Speicher (per new) allokieren muss. Anders ausgedrueckt: mit 'new'/'delete' sollte man so umgehen wie mit '?alloc'/'free' in C.
Aber selbst in den Beispielen von Qt finde ich immer nur sowas: QSqlCursor cur( "prices" );
Auch du solltest dich in die _GRUNDLAGEN_ von C++ einlesen! Insbesondere auch bzgl. new/delete vs. "automatische" Stack-Variablen. -dnh --
"Gah. You know there's people apparently people paying for pr0n feeds for their cellphone." -- Peter da Silva "Yeah, I know. I helped build the infrastructure." -- Matt McLeod [sig courtesy of AdB]
Am Dienstag, 22. November 2005 15:14 begab es sich, daß Ludwig Fromke folgendes in den Rechenknecht kloppte:
Hallo Liste
Ich muß vorausschicken das ich gerade meine ersten Gehversuche mit Qt und C++ unter Suse Linux 9.3 mache. Die vorangegangene Diskusion (frage zu Objekten in c++) hat mir viel geholfen. Jetzt fehlt mir nur noch etwas zum richtigen Verständnis der Materie. In der Doku von QT unter QSqlCursor habe ich etwas gefunden was nicht richtig verstehe. (liegt wohl auch an meinen schlechten Englisch) Da steht das QT den Cursor nicht automatisch löscht sondern ich dafür verantwortlich bin. Ich stelle mir das jetzt einfach mal so vor: QSqlCursor *cursor = new QSqlCursor; delete cursor; (Hoffentlich stimmt das so)
So stimmt's erstmal.
Aber selbst in den Beispielen von Qt finde ich immer nur sowas: QSqlCursor cur( "prices" ); Eigentlich habe ich gedacht das sich solche Variablen von selbst töten wenn die Funktion beendet wird. (Stimmt das?) (Wie ist das eigentlich mit Variablen die ich im Konstruktor definiere? Wann sterben die?)
Du stehst in der Tat ziemlich am Anfang eines langen und faszinierenden Weges. Aber zu deiner Frage: Man kann Variabelen - vereinfacht ausgedrückt - auf zwei Arten deklarieren. Einmal auf dem Stack, das ist so, wie es in den Tutorials steht. Diese Variabelen werden automatisch gelöscht, wenn ihr Gültigkeitsbereich verlassen wird. Dieser geht - wieder vereinfacht ausgedrückt - von der der Deklaration voranstehenden {-Klammer bis zu der ihr zugehörigen Schliessklammer. Stack-Variabelen sind gut, wenn man "mal eben was wegschreiben" will. Diese Variabelen deklariert man daher auch nicht im Konstruktor, weil sie mit ihm gemeinschaftlich sterben. Für langlebige Variabelen nimm man den Heap. Deine erste Deklaration erzeugt ein solches Objekt. Dabei passieren mehrere Dinge: Zunächst deklarierst du einen Zeiger vom Typ QSqlCursor, das ist eine int-Variabele, in die eine Speicheradresse eingetragen wird. Dann initialisierst du diesen Zeiger, indem du ihm z.B. so wie du es gemacht hast, per new neuen Speicher reservierst. Weil du aber explizit Soeicher reserviert hast, must du diesen auch explizit wieder zurückgeben. Dafür sorgt der delete-Aufruf. Der Zeiger, den du zu Anfang deklariert hast, zeigt nun zwar immer noch auf den Speicherbereich, aber der gehört dir nun nicht mehr und könnte vom System einem anderen Prozess oder Thread zugewiesen werden.
Die Frage ist nun wie ich einen QSqlCursor richtig töte? Und gibt es noch mehr solche Qt-Objekte die ich selber töten muss?
Wie gesagt, es kommt drauf an, wie du ih deklarierst. Ich leg mir das Ding immer auf den Heap; weil ich ihn dann garantiert klassenweit verwenden kann. Auch habe ich mir angewöhnt, alle Objekte spätestens im Destruktor zu deleten, egal, was die Qt-Doku sagt. sicher ist sicher.
Da ich immer wieder bei meinen Dialogen, die viel mit SQL arbeiten, das Problem habe das beim zweiten Start ein SegFault kommt wäre ich für etwas Hilfe sehr dankbar.
Dann will ich mal hoffen, daß ich hilfreich sein konnte. -- --- Grüsse aus Meissen Jörg Pauly
Hi Ludwig, Ludwig Fromke schrieb am 22.11.2005 15:14:
Ich muß vorausschicken das ich gerade meine ersten Gehversuche mit Qt und C++ unter Suse Linux 9.3 mache. Die vorangegangene Diskusion (frage zu Objekten in c++) hat mir viel geholfen. Jetzt fehlt mir nur noch etwas zum richtigen Verständnis der Materie.
Du gehst schonmal den richtigen Weg. Man lernt nur, wenn man sich auch traut zu fragen und selbst Fehler zu machen. - Unerlässlich ist aber in jedem Fall ein _gutes_ C++-Buch (damit meine ich nicht "C++ in 21 Tagen"). C++ ist wirklich nicht mein Spezialgebiet, aber ich denke, dass ich die Konzepte verstanden habe. Also werde ich mal versuchen, deine Fragen zu beantworten. Von QT habe ich allerdings keinen blassen Schimmer...
In der Doku von QT unter QSqlCursor habe ich etwas gefunden was nicht richtig verstehe. (liegt wohl auch an meinen schlechten Englisch) Da steht das QT den Cursor nicht automatisch löscht sondern ich dafür verantwortlich bin. Ich stelle mir das jetzt einfach mal so vor: QSqlCursor *cursor = new QSqlCursor; delete cursor; (Hoffentlich stimmt das so)
Vorausgesetzt, dass es diesen Default-Konstruktor gibt, sieht es gut aus.
Aber selbst in den Beispielen von Qt finde ich immer nur sowas: QSqlCursor cur( "prices" ); Eigentlich habe ich gedacht das sich solche Variablen von selbst töten wenn die Funktion beendet wird. (Stimmt das?)
Naja, ein bisschen mehr Unterschiede gibt es da schon: Solche Objekte werden nicht auf dem HEAP, sondern auf dem Stack erzeugt. - Sie werden entsorgt (mit dem Destruktor), sobald ihr Gültigkeitsbereich verlassen wird. - Der Gültigkeitsbereich hängt davon ab, wo sie deklariert wurden. Es kann auch eine Funktion sein.
(Wie ist das eigentlich mit Variablen die ich im Konstruktor definiere? Wann sterben die?)
Wenn sie erst im Konstruktor deklariert werden, dann sterben sie, sobald der Konstruktor abgearbeitet wurde. - Sind es Eigenschaften des Objekts, die nur im Konstruktor definiert werden, dann sterben sie, wenn das Objekt zerstört wird.
Die Frage ist nun wie ich einen QSqlCursor richtig töte?
Kommt darauf an, wie du ihn erzeugst. Ob und warum man ihn selbst entsorgen muss, selbst wenn er auf dem Stack angelegt wird, weiß ich mangels QT-Kenntnis nicht. Ist QT OpenSource? Dann schau doch einfach mal in die Quellen des QSQLCursors und versuche, einen Grund zu finde, warum der Cursor nicht automatisch entsorgt werden kann.
Und gibt es noch mehr solche Qt-Objekte die ich selber töten muss?
Weiß ich nicht.
Da ich immer wieder bei meinen Dialogen, die viel mit SQL arbeiten, das Problem habe das beim zweiten Start ein SegFault kommt wäre ich für etwas Hilfe sehr dankbar.
Den Segfault kann ich dir auch nicht erklären. Gruß, Michael
Hallo, Am Tue, 22 Nov 2005, Michael Wenger schrieb:
Ludwig Fromke schrieb am 22.11.2005 15:14:
Ich muß vorausschicken das ich gerade meine ersten Gehversuche mit Qt und C++ unter Suse Linux 9.3 mache. Die vorangegangene Diskusion (frage zu Objekten in c++) hat mir viel geholfen. Jetzt fehlt mir nur noch etwas zum richtigen Verständnis der Materie.
Du gehst schonmal den richtigen Weg. Man lernt nur, wenn man sich auch traut zu fragen und selbst Fehler zu machen. - Unerlässlich ist aber in jedem Fall ein _gutes_ C++-Buch (damit meine ich nicht "C++ in 21 Tagen").
Ich wuerde den Stroustrup[1] empfehlen. Keine einfache Lektuere, aber eine, die eine solide Grundlage liefert. Einzig ein paar C-Erbschaften (Pointer/Dereferenzieren) werden nicht ganz so ausfuehrlich behandelt, da hat mir der K&R[2] sehr geholfen. -dnh [1] z.B. http://www.amazon.de/exec/obidos/ASIN/382731660X/slfaq-21/ [3] [2] z.B. http://www.amazon.de/exec/obidos/ASIN/0131103628/slfaq-21/ noch weniger einfache Lektuere, aber mind. ebenso solide. [3] die Ausgabe kenne ich selber nicht, ich habe aber die 3te Auflage der deutschen Ausgabe. PS: ueber obige Links kannst du die SUSE-Linux-FAQ unterstuetzen, wenn man bei Amazon bestellt sollte man das /slfaq-21/ anfuegen, ansonsten bestellt bitte im lokalen Buchhandel oder bei lob.de und lasst anderen Projekten einen kleinen Beitrag zukommen (z.B. wenn man via dante.de zu lob.de geht kann man das LaTeX Projekt unterstuetzen), die URL-"Syntax" bei lob.de weiss ich jetzt aber gerade nicht. Auch Debian kann man AFAIR via Kauf bei lob.de unterstuetzen. Klappt (bei Amazon) uebrigens mit allen Buechern (bei anderen Artikeln weiss ich's nicht). Das sind zwar nur Kleckerbetraege, aber das summiert sich, und kann z.B. schnell nen Monat Webhosting (z.B. der SUSE-Linux-FAQ) finanzieren... -- Es geht doch nichts über eine Protion "Weisheit" . Die wäscht den grauen Alltag einfach weg. [WoKo in dag°]
David Haller
PS: ueber obige Links kannst du die SUSE-Linux-FAQ unterstuetzen, wenn man bei Amazon bestellt sollte man das /slfaq-21/ anfuegen, ansonsten bestellt bitte im lokalen Buchhandel oder bei lob.de und lasst anderen Projekten einen kleinen Beitrag zukommen (z.B. wenn man via dante.de zu lob.de geht kann man das LaTeX Projekt unterstuetzen), die URL-"Syntax" bei lob.de weiss ich jetzt aber gerade nicht. Auch Debian kann man AFAIR via Kauf bei lob.de unterstuetzen. Klappt (bei Amazon) uebrigens mit allen Buechern (bei anderen Artikeln weiss ich's nicht). Das sind zwar nur Kleckerbetraege, aber das summiert sich, und kann z.B. schnell nen Monat Webhosting (z.B. der SUSE-Linux-FAQ) finanzieren...
OT: http://www.bookzilla.de ist auch nicht schlecht (das Geld geht an die FSF Europe). Gruß, Bernhard -- Wenn Du ein Schiff bauen willst, so trommle nicht Männer zusammen, um Holz zu beschaffen, Werkzeuge vorzubereiten, Aufgaben zu vergeben, und die Arbeit einzuteilen, sondern lehre die Männer die Sehnsucht nach dem weiten endlosen Meer. -- Antoine de Saint-Exupery
Hallo, Am Tue, 22 Nov 2005, Bernhard Walle schrieb:
David Haller
[2005-11-22]: [Open Source Projekte per Buchkauf unterstuetzen] OT: http://www.bookzilla.de ist auch nicht schlecht (das Geld geht an die FSF Europe).
ACK! Stimmt. Die hab' ich vergessen. -dnh -- Proof that they're lusers who must die: they send spam saying "Restore your sex life" even though they never told you to back it up. - - AdB
wo wir grade bei büchern sind, ich hab "einstig in c++" 2. Auflage von Arnold Willemer (gibt es glaub ich auch online http://www.willemer.de/informatik/cpp/index.htm) und bin damit sehr zufrieden. greatz Johannes -- Es gibt 10 Arten von Menschen auf dieser Welt, die einen verstehen das Binärsystem und die anderen verstehen es nicht.
Am 22 Nov 2005 um 22:51 hat David Haller geschrieben: Hallo, http://www.onlinelesen.de/ und darin verlinkt http://www.maththinking.com/boat/computerbooks.html Vieeeel Bücher :-) Lothar
Hallo,
Am Tue, 22 Nov 2005, Bernhard Walle schrieb:
David Haller
[2005-11-22]: [Open Source Projekte per Buchkauf unterstuetzen] OT: http://www.bookzilla.de ist auch nicht schlecht (das Geld geht an die FSF Europe). ACK! Stimmt. Die hab' ich vergessen.
-dnh
-- Proof that they're lusers who must die: they send spam saying "Restore your sex life" even though they never told you to back it up. - - AdB
-- Um die Liste abzubestellen, schicken Sie eine Mail an: suse-programming-unsubscribe@suse.com Um eine Liste aller verfügbaren Kommandos zu bekommen, schicken Sie eine Mail an: suse-programming-help@suse.com
-- Lothar Behrens | Rapid Prototyping ... Rosmarinstr 3 | 40235 Düsseldorf | www.lollisoft.de
participants (8)
-
adsci
-
Bernhard Walle
-
David Haller
-
Johanns Schneider
-
Jörg Pauly
-
lothar.behrens@lollisoft.de
-
Ludwig Fromke
-
Michael Wenger