wxFileDialog richtig deleten



  • Hi,

    ich hab folgendes Problem:

    Wenn ich einen wxFileDialog aufrufe, werden von wxWidgets(?) dafür 3 neue Threads angelegt. (ich selbst starte sie jedenfalls nicht!)
    Wenn er beendet ist, rufe ich Destroy() auf, damit der Speicher freigegeben wird.
    Aber weder der Speicher wird freigegeben, noch die Threads werden beendet.
    Somit habe ich 3 überflüssige Threads im Programm. Nach einiger Zeit beenden sich zwei von ihnen. Aber der letzte Thread bleibt.

    Wie kann ich den FileDialog richtig beenden?

    Es ist mir auch aufgefallen, dass bei einem erneuten Öffnen eines anderen Dialoges gar kein weiterer Speicher mehr belegt wird.

    Mfg


  • Mod

    Zeig mal deinen Code. Und wo siehst du die 3 Threads? Und welche Plattform verwendest du?

    Generell kannst du einen FileDialog auch auf dem Stack anlegen:

    void MyFrame::foo()
    {
      wxFileDialog dlg;
      dlg.ShowModal();
    }//hier wird er dann zerstört.
    


  • Ok, sorry.

    Also ich verwende Visual Studio 2005 , also Windowsplattform.

    Ich schau mir halt die Werte im Windows Task-Manager an. Bis ich durch einen Klick auf einen Button den Dialog öffne, ist alles normal. 1 Thread, und 6MB Speicher.

    wxFileDialog *file_dlg = new wxFileDialog(this,_("Datei auswählen"),wxT(""),wxT(""),_T("*.*"),wxOPEN|wxFILE_MUST_EXIST);
      file_dlg->ShowModal();
    
      path = file_dlg->GetPath();
      file = file_dlg->GetFilename();
    
      path_tctrl->AppendText(path);
    
      file_dlg->Destroy();
    

    Ich leg den Dialog immer mit new an. Hat den Grund, da ich mal gelesen hab, dass man wxWidgets Grafikelemente immer mit new anlegen sollte.
    (Stimmt es, dass wxWidgets zu einem gewissen Maß die Speicherverwaltung übernimmt?) Zumindest werden ja alle Childs gelöscht, wenn man einen delete auf das Parent macht!?
    Ich hab deinen Code versucht, läuft auch wunderbar, aber leider sind die Threads immer noch da und der Speicher auch. Wenn ich das Fenster minimiere und wieder öffne, ist der Speicherverbrauch auf Normalniveau gesunken.

    Mfg


  • Mod

    Also ich seh da gerade keinen Unterschied. Was das löschen betrifft, das gilt für Steuerelemente z.B. in einem Panel.
    Bei Dialogen etc. musst du dich selber drum kümmern, aber das tust du ja.

    Es kann so sein, das wxWidgets das Beenden dem OS nur signalisiert, und dieses dann etwas später dies tut, oder einfach der Programmspeicher
    wird erst etwas später wieder freigegeben, während der Dialog schon zerstört ist.



  • Ich weiß zwar nicht, was

    file_dlg->Destroy();
    

    tut, aber zu einem new gehört meines Wissens auch ein delete.

    Schau mal was passiert, wenn du noch ein

    delete file_dlg;
    

    hinzufügst.



  • Das Destroy() löscht ein wxWindow(wozu auch ein FileDialog gehört) auf sichere Art und Weise. Laut Doku soll man nicht den Destruktor direkt aufrufen.
    Zitat wxWidgets Doku:

    wxWindow::Destroy

    virtual bool Destroy()

    Destroys the window safely. Use this function instead of the delete operator, since different window classes can be destroyed differently. Frames and dialogs are not destroyed immediately when this function is called -- they are added to a list of windows to be deleted on idle time, when all the window's events have been processed. This prevents problems with events being sent to non-existent windows.

    Return value

    true if the window has either been successfully deleted, or it has been added to the list of windows pending real deletion.

    Das delete haut ein Fenster einfach weg. Aber vielleicht ist gerade das die Lösung. Werd's mal ausprobieren.

    Mfg


  • Mod

    The-Kenny schrieb:

    Ich weiß zwar nicht, was

    file_dlg->Destroy();
    

    tut, aber zu einem new gehört meines Wissens auch ein delete.

    Schau mal was passiert, wenn du noch ein

    delete file_dlg;
    

    hinzufügst.

    Das Destroy sollte dies bereits erledigen, ein direktes delete ist wie firewall schon sagt, in wxWidgets nicht empfehlenswert.
    Evtl. erstellst du den Dialog mal mit NULL als Parent, das könnte noch etwas ändern.



  • phlox81 schrieb:

    Das Destroy sollte dies bereits erledigen, ein direktes delete ist wie firewall schon sagt, in wxWidgets nicht empfehlenswert.
    Evtl. erstellst du den Dialog mal mit NULL als Parent, das könnte noch etwas ändern.

    Ansonsten nimm doch mal einen Memory-Debugger. valgrind ist sehr gut, aber ich weis nicht, ob es ihn auch für Windows gibt. Dein Speicherleck, könnte ja von überall herkommen...


Anmelden zum Antworten