bad_alloc und qt
-
Hi
ich habe angefangen, mich ein wenig mit Qt zu beschäftigen und stoße in dem GettingStarted-Artikel immer wieder auf so was:
Notepad::Notepad() { textEdit = new QTextEdit; quitButton = new QPushButton(tr("Quit")); connect(quitButton, SIGNAL(clicked()), this, SLOT(quit())); QVBoxLayout *layout = new QVBoxLayout; layout->addWidget(textEdit); layout->addWidget(quitButton); setLayout(layout); setWindowTitle(tr("Notepad")); }
wie löst ihr so was? unique_pointer (oder allg smart_pointer) oder eher "wird schon gut gehen"? manuell try/catch drum geht ja schon bei so kleinen bsp nicht mehr auf einer ebene durch die besitzübergabe...
bb
-
Das Tutorial ist eigentlich falsch.
Edit: Das Tutorial ist nicht wirklich falsch es ist nur so ein einfaches Beispiel, dass man kein Parent hat aber sobald dein MainWindow eine richtige Klasse ist, hast du fuer deine Widgets ein Parent.Bei new Qirgendwas solltest Du immer ein Parent angeben ansonsten musst Du es immer selber wegraeumen, wenn Du das machst sollte es keine memory leaks geben, weil sobald der Destruktor des Parent aufgerufen wird, wird die Resource aufgeraeumt.
//e.g. get_releases_Class is MainWindow actionImport_Rule = new QAction(get_releasesClass); // source_lbl = new QLabel(layoutWidget);
-
Das parent-child System löst das Problem der möglichen bad_alloc Exceptions nicht, darauf wollte unskilled wohl hinaus (steht zumindest im Titel, nicht mehr im Text).
Wir ignorieren bad_alloc grundsätzlich. Was soll man denn großartig sinnvolles machen, wenn der Speicher nicht reicht?
Alle Exceptions und Crashes werden bei uns aber im Endeffekt abgefangen und es werden Dumps geschrieben (wir haben auch ein entsprechendes Tool, um Supportanfragen zu erstellen) und ein Fehlerdialog angezeigt.
-
also läuft alles auf smart pointer hinaus oder eben auf diese bad_alloc ist mir doch egal-einstellung.
aber find diese "ich hab zu wenig RAM, also hab ich eben memory leaks"-einstellung iwie... komisch^^
abgesehen davon ist es ja nun mal tatsache, dass ein CTor nicht nur bad_alloc werfen kann.dachte nur, dass es iwie ne best-practice lösung gibt. ich bin da eher so der ästhetische programmierer - es muss nicht nur funktionieren sondern eben in jeder situation. und schön aussehen ;o)
bb
-
Es sollte keine Memory Leaks geben.
layout->addWidget(textEdit);
übergibt dem textEdit sein Parent Objekt. Wenn das Parent Objekt gelöscht wird, löscht es alle Children mit.
Exception Safe ist es in der Form aber natürlich nicht. Das Reparenten passiert in deinem Beispiel erst in Zeile 12, bei setLayout. Wenn dazwischen eine Exeption fliegt, die später irgendwo gefangen wird, hast du Memory Leaks.Ich halte diese Probleme für sehr hypothetisch. Wir haben eine Software mit rund 6 Mio Zeilen Code, die seit 20 Jahren entwickelt wird und bei vielen Kunden im Einsatz ist. Und wir haben diese Probleme nicht. Schon gar nicht in der GUI.
p.s. Etwas besser ist, den Objekten gleich im Konstruktor einen Parent mitzugeben, dann haben die schon mal gleich einen Parent und es kann nicht so viel schiefgehen, bis sie endlich mal einen bekommen. Aber wie gesagt, wir haben diese Probleme in der Praxis einfach nicht.
-
Dieser Thread wurde von Moderator/in Arcoth aus dem Forum C++ (alle ISO-Standards) in das Forum Andere GUIs - Qt, GTK+, wxWidgets verschoben.
Im Zweifelsfall bitte auch folgende Hinweise beachten:
C/C++ Forum :: FAQ - Sonstiges :: Wohin mit meiner Frage?Dieses Posting wurde automatisch erzeugt.
-
den Objekten gleich im Konstruktor einen Parent mitzugeben, dann haben die schon mal gleich einen Parent und es kann nicht so viel schiefgehen
hm? wenn ich die doku richtig verstehe kann dann gar nichts schief gehen (was ich beeinflussen kann - ob intern alles exception-safe ist, kann mir ja egal sein, weil ichs eh nicht ändern kann)?!
nur die ohne-parent-variante (die im tut natürlich ausschließlich verwendet wird), finde ich doof.bb
-
unskilled schrieb:
dachte nur, dass es iwie ne best-practice lösung gibt. ich bin da eher so der ästhetische programmierer - es muss nicht nur funktionieren sondern eben in jeder situation. und schön aussehen ;o)
Dann erklaer mir mal bitte was Du machen willst, wenn eine bad_alloc_exception geworfen wird.
Das Programm kann dann einfach nicht mehr anstaendig weiter funktionieren und das Programm zu beenden ist schlicht und ergreifend die einzige richtige Aktion.Auch noch mal so nebenbei, wenn in deinem Programm die Gefahr besteht, dass Du e.g. in 32bit Applikationen an die 2GB Grenze kommen koenntest solltest Du deine Architektur ueberdenken.
Bad_alloc ist eigentlich nur ein theoretisch/hypothetisches Problem aber in dem Moment in dem es tatsaechlich passieren kann musst Du deine Architektur umbauen.
Stichwort: load on demand + eingebauten cache
Meines Wissens werfen die Konstruktoren von QWidgets nicht -(ausser bad alloc) aber das wurde schon angesprochen- und wie mechanics schon sagte Du solltest bereits im Konstruktor einen Parent angeben danach kann bei StandardWidgets eigentlich nichts mehr schiefgehen.
(Ich wuesste jedenfalls keinen Fall in dem da was schiefgehen kann, es sei denn natuerlich Du hast ein "eigenes" Widget von einem standard Widget abgeleitet und in deinem Konstruktor wird irgendwas geworfen.
Aber darum musst Du dich dann natuerlich selber kuemmern.)
-
Qt selber nutzt keine Exceptions, daher wird bad_alloc auch nicht berücksichtigt.
Was bad_alloc angeht, ohne catch wird std::terminate aufgerufen, was häufig auch ein korrektes Verhalten darstellt, da es offensichtlich nicht die Resourcen aktuell gibt das Programm auszuführen. Wenn du ein anderes Verhalten willst, musst du eben try/catch nutzen.