Qt und eigene Speicherverwaltung



  • Hallo,

    besitzt Qt eine eigene Speicherverwaltung?
    Ich meine jetzt nicht, dass ich das delete so gut wie nie anwenden muss. Sondern, ob Qt eine Vorsorge für die Fragmentierung des Speichers besitzt.

    Gruß,
    Thomas



  • Was für Probleme hast du mit Speicher Defragmentierung?



  • erzählmal schrieb:

    Was für Probleme hast du mit Speicher Defragmentierung?

    Wer sagt was von Probleme? Aktuell keine. Ich versuche mich nur zu informieren, ob Qt etwas in dieser Richtung unternimmt.

    Falls nicht. Benutzt Qt ausschließlich new und delete? Könnte man durch überschreiben dieser Operatoren eine eigene Speicherverwaltung anhängen?



  • Würde mich sehr überraschen, wenn die sowas machen. Das Problem wird sogut wie keiner haben. Wieso brauchst du eine eigene Speicherverwaltung? Was willst du programmieren und was für Probleme erwartest du?



  • Die Arten von Speicherverwaltung, die ich von Qt kenne, sind:
    1. Parents löschen ihre Children, wenn sie selbst gelöscht werden (glaube ich zumindest)
    2. Qt stellt auch Shared Pointer zur Verfügung. Stichwort: QPointer<T>. Es gibt aber auch andere Pointer-Typen.



  • Siassei schrieb:

    Sondern, ob Qt eine Vorsorge für die Fragmentierung des Speichers besitzt.

    Wie meinst du Vorsorge? Techniken wie Speicherverdichtung und Verschiebung einzelner Objekte im Speicher wird in C++ nicht ohne Weiteres funktionieren, da es Zeiger und Referenzen ungültig machen würde.

    wxSkip schrieb:

    Die Arten von Speicherverwaltung, die ich von Qt kenne, sind [...]

    Das hat nichts mit Fragmentierung zu tun.



  • Nexus schrieb:

    wxSkip schrieb:

    Die Arten von Speicherverwaltung, die ich von Qt kenne, sind [...]

    Das hat nichts mit Fragmentierung zu tun.

    Ups, zu schnell gelesen...

    Defragmentierung ist schwierig zu vermeiden. Es gibt AFAIK zwei Möglichkeiten. Die erste ist, die Objekte an einer möglichst sinnvollen Adresse zu erstellen, was new und malloc() AFAIK bereits tun.
    Die zweite wäre, die Objekte umzuordnen. Dazu müssten aber alle Pointer auf das Objekt mit abgeändert werden, außerdem müsste man Pointer, die in einem String, einem long oder sonst etwas gespeichert sind, berücksichtigen. Und das ist unrealistisch, schwierig bis unmöglich zu realisieren und selbst mit Pointer-Klassen äußerst heikel, außerdem ist die Portabilität nicht gegeben.

    Fazit: Defragmentierung ist nicht das Problem von Qt, sondern ein Allgemeines.



  • wxSkip schrieb:

    Die zweite wäre, die Objekte umzuordnen. Dazu müssten aber alle Pointer auf das

    Da hast du wohl noch drittens und viertens vergessen 😃
    Spaß bei Seite. Als Fazit bis jetzt halte ich mal fest, dass in Qt keine Techniken zur Speicherverwaltung /- ordnung eingesetzt werden.

    Eines bleibt noch offen. Ist Qt sauber programmiert?
    Sprich, es benutzt intern nur new und delete und kein malloc, ...
    Trifft das zu? Wie könnte man so etwas testen?



  • Wie es intern abläuft, ist nicht so zentral, solange es gut läuft. Viel wichtiger ist das API. Meiner Meinung nach hängt die Qualität eines Frameworks unter Anderem von folgenden Punkten ab:

    • Sind die Dinge einfach und intuitiv anzuwenden?
    • Folgen sie gängigen Konventionen oder erlebt man Überraschungen?
    • Werden moderne C++-Sprachmittel eingesetzt?
    • Kann man mit wenig Code viel erreichen?
    • Sind die Aufgaben gut auf verschiedene Klassen und Funktionen verteilt?
    • Wie gut ist alles dokumentiert?
    • ...


  • Siassei schrieb:

    Sprich, es benutzt intern nur new und delete und kein malloc, ...

    malloc wird intern auch verwendet. Es gibt so gar eine Wrapperfunktion namens qMalloc. Ich sehe darin aber auch kein Problem.



  • Was soll das Problem an einer Fragmentierung des Speichers sein?



  • nachgefragt schrieb:

    Was soll das Problem an einer Fragmentierung des Speichers sein?

    Kein Platz für große zusammenhängende Daten (std::vector<T>, ...) usw.



  • wxSkip schrieb:

    Kein Platz für große zusammenhängende Daten (std::vector<T>, ...) usw.

    Dafür gibt es verkettete Listen (std::list).



  • EOutOfResources schrieb:

    wxSkip schrieb:

    Kein Platz für große zusammenhängende Daten (std::vector<T>, ...) usw.

    Dafür gibt es verkettete Listen (std::list).

    Manchmal braucht man halt Speicher am Stück, wenns schnell gehen soll, aber heut zu tage wo schon jeder privat PC bald 4GB hat sollte man eigentlich genug haben, sonst steckt man halt 16 oder 32 GB rein.



  • Die c't hatte mal ein Tool/Library für Windows getestet, das man in sein C++ Projekt einbinden konnte. Damit wurde der Speicher defragmentiert. Und das entscheidende war, das das Programm eine bessere und nennenswerte Performance aufwies. Ich weiß leider nicht mehr wie das Tool hieß. Es war irgendwas mit Smartmemory oder so.

    Es gibt ja genug Programme, wie Cinema 4D, die eine eigene Speicherverwaltung haben. Wer die Plug-ins für C4D mittels C++ entwickelt, weiß das. Anscheinend lohnt es sich.

    In "Modernes C++ Design" steht, das der Allocator der C++ Runtimes nur ein Kompromiss ist, und bei sehr vielen kleinen Objekten nicht optimal sei. Ob es heute noch stimmt?



  • Nexus schrieb:

    Wie es intern abläuft, ist nicht so zentral, solange es gut läuft. Viel wichtiger ist das API. Meiner Meinung nach hängt die Qualität eines Frameworks unter Anderem von folgenden Punkten ab:

    • Sind die Dinge einfach und intuitiv anzuwenden?
    • Folgen sie gängigen Konventionen oder erlebt man Überraschungen?
    • Werden moderne C++-Sprachmittel eingesetzt?
    • Kann man mit wenig Code viel erreichen?
    • Sind die Aufgaben gut auf verschiedene Klassen und Funktionen verteilt?
    • Wie gut ist alles dokumentiert?
    • ...

    Ich stimme Dir zu, nur bleiben dann nicht mehr viele GUI-Frameworks übrig. Qt fällt z.B. flach.



  • Das könnte man aber ändern! 😃
    Übrigens, Issue 85 ist fixed!



  • Artchi schrieb:

    Das könnte man aber ändern! 😃
    Übrigens, Issue 85 ist fixed!

    Muss ich mir mal angucken. 😉 Die (Online Handbook) Doku ist noch nicht angepasst, oder?
    Außerdem: (jaja, ist OT) Gibt es bei den Textfeldern irgendwie eine Möglichkeit, auf Keypress-Events zu lauschen? Irgendwie bekomme ich es nur hin, allgemein auf Änderungen zu reagieren. Ich würde aber z.B. gerne einen Text in einen std::string übernehmen, wenn Enter gedrückt wurde.

    Sieht vereinfacht so aus:

    class MyObserver : public oran::observer
    {
    public:
        MyObserver
            ( algier::field_ptr observed )
        : m_observed(observed)
        { }
    
        virtual void subject_killed()
        {
            std::cout << "Subject is dead now!\n";
        }
    
        virtual void update()
        {
            //wird bei jeder aenderung an "text" aufgerufen...
            std::wcout << m_observed->model().str() << '\n';
        }
    private:
        algier::field_ptr m_observed;
    };
    
    int main()
    {
        //...
        algier::field_ptr text(new algier::textfield(5));
    
        MyObserver obs(text);
    
        text->model().attach(obs);
    
       //...
    }
    

    Ich bin mir aber nicht so sicher, ob ich das richtig machen, oder irgendwas übersehen habe.



  • Die Online-Doku ist nicht aktualisiert. Das mache ich immer nur bei einem Release (bald in 2 Monaten). Die Doku wurde aber schon bei mir lokal geändert, ich muss sie demnächst in das Repo ein-checken.

    Zu deiner Frage: Tastenereignisse kann man leider noch nicht abfragen. Bisher gehen nur Mausereignisse, wenn wir von HIDs ausgehen. Ist aber in Issue 75 vermerkt und ist auch für das nächste Release eingeplant.

    text->model().str() wäre schon mal der richtige Schritt. Um auf RETURN-Key zu reagieren, würde das für die nächste Version nach Schema-F für die Events ablaufen:
    http://www.kharchi.eu/algierlib/events.html

    Beispiel:

    field_ptr text(textfield::create(5));
    text->connect_key_released( apply_str ); // ab v0.6.0
    
    void apply_str(const key_t &k)
    {
      if( k.key() == vk_return)
         text->model().str(); // irgendwas mit dem String aus dem Eingabefeld machen
    }
    

    So oder ähnlich wird das wohl mit dem nächsten Release ablaufen. Mit Mausereignissen läuft das auch so im 2D-GFX-Test (siehe init()) schon länger. Ich denke, das ist 'ne gute Praxis.


Anmelden zum Antworten