[gelöst] wxWidgets: double free or corruption (out)



  • Noch kurz als Vorwarnung: Ich habe noch nicht so viel Erfahrung mit C++ und in wxWidgets ist es mein erstes Projekt. Ich kämpfe mich noch durch die Dokumentationen. Sollte es eine DAU-Frage sein, möchte ich mich entschuldigen, aber ich finde weder in Google noch auf wxwidgets.org ne Lösung oder einen Ansatz.

    Hallo,
    ich verzweifel fast, weil ich das Problem nicht finde. Ich mache etwas, was in Klassen ohne wxWidgets immer funktioniert, aber mit wx auf einmal zu diesem Fehler führt (siehe Titel).

    Ich möchte ein Programm schreiben, über das ich kurze Textnachrichten im Netzwerk verschicken kann. Dazu brauche ich ein Serverprogramm und einen Clienten. Das Problem macht mir der Client. Ich möchte in der Variable ServerAdr die IP vom Server speichern.

    Folgendes habe ich bereits geschrieben:

    Header:

    #ifndef _CLIENT_APP_H_
    #define _CLIENT_APP_H_
    
    #include <wx/wx.h>
    #include <wx/app.h>
    #include <wx/string.h>
    #include "client_basisfrm.h"
    
    class ClientApp : public wxApp
    	{
    	private:
    		wxString *ServerAdr;
    
    	public:
    		virtual bool OnInit();
    		virtual int OnExit();
    	};
    
    #endif // _CLIENT_APP_H_
    

    Code:

    #include <wx/wx.h>
    #include <wx/app.h>
    #include <wx/string.h>
    #include "client_app.h"
    #include "client_basisfrm.h"
    
    bool ClientApp::OnInit()
    	{
    	// Init
    	SetAppName(wxT("Client") );
    	SetVendorName(wxT("Client") );
    	// Server Standard
    	ServerAdr = new wxString(wxT("192.168.0.33") );
    	// Basis-Frame
    	ClientBasisFRM *frame = new ClientBasisFRM( wxT("Client"), 50, 50, 450, 300);
    	frame->Center();
    	frame->Show(true);
    	SetTopWindow(frame);
    	return true;
    	}
    
    int ClientApp::OnExit() {
    	delete ServerAdr;
    	return wxApp::OnExit();
    }
    

    Die Zeile "ServerAdr = new wxString(wxT("192.168.0.33") );" macht die Probleme. Wenn ich diese entnehme (und auch das delete im OnExit) dann läuft das Programm einwandfrei. Lasse ich die Zeile (egal ob mit oder ohne delete) dann beendet sich das Programm nach dem Start sofort und ich bekomme folgenden Text in der Konsole:

    *** glibc detected *** bin/client: double free or corruption (out): 0x0807f8d0 ***
    ======= Backtrace: =========
    /lib/libc.so.6[0xb757cfc4]
    /lib/libc.so.6(cfree+0x9c)[0xb757e95c]
    /usr/lib/libglib-2.0.so.0(g_free+0x36)[0xb6fb5426]
    /usr/lib/libglib-2.0.so.0[0xb6faccb7]
    /usr/lib/libglib-2.0.so.0(g_main_context_dispatch+0x2b1)[0xb6fad3a1]
    /usr/lib/libglib-2.0.so.0[0xb6fb085b]
    ......und viele Zeilen mehr
    

    Was mich wundert: Wenn die diese Konstellation in einer nicht wx-geerbten Klasse schreibe, dann klappt das. Auch mein schlaues Buch sagt mir, dass ich es richtig mache. Liegt es daran, dass wxWidgets ja eigentlich keinen richtigen Konstruktor anbietet sondern die Funktion OnInit??
    Ich weiß nicht mehr weiter.

    Die Variable will ich deswegen zentral in der ClientApp speichern, weil die Varibale später selbst veränderbar werden soll. (Über irgendein wxDialogDings, so weit bin ich noch nicht.)

    g++ --version

    g++ (SUSE Linux) 4.3.1 20080507 (prerelease) [gcc-4_3-branch revision 135036]
    Copyright (C) 2008 Free Software Foundation, Inc.
    This is free software; see the source for copying conditions.  There is NO
    warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
    

    wx-config --version

    2.8.8
    


  • Nunja, so wie es aussieht kann sich niemand den Fehler erklären. Ich habe nun die Variable auf die gleiche Art und Weise in meinen BasisFRM gepackt. Das geht jetzt. Allerdings ist das nicht die Lösung die ich mir vorstelle, denn ich würde gerne vor der Erstellung des Frames die Verbindung aufbauen. Jetzt muss ich den Frame laden und wenn die Verbindung scheitert, dann den Frame wieder schließen.

    Wenn trotzdem jemand noch eine Lösung hätte, würde ich mich noch über einen Beitrag freuen.

    Für alle die schon mal über mein Problem nachgedacht haben: Danke!


  • Mod

    Seh da zwar keinen direkten Fehler, aber normalerweise verwendet man keine Pointer für Strings. Dann müsste es auch in der App Klasse klappen.



  • Jetzt kommt die DAU-Anfängerfrage:
    Wieso keine Pointer für wxStrings?


  • Mod

    stefanjann schrieb:

    Jetzt kommt die DAU-Anfängerfrage:
    Wieso keine Pointer für wxStrings?

    warum? darum. Pointer sollte man eigentlich vermeiden, wenn man sie nicht braucht.

    class A
    {wxString str;}//str ist immer korrekt initialisiert
    


  • stefanjann schrieb:

    Wieso keine Pointer für wxStrings?

    Weil die meisten wxWidgets-Typen einen internen reference-count haben.



  • OK, nun hab ich die Pointer raus und siehe da: Es geht tatsächlich. (*newbee-Verwunderung*)

    Allerdings habe ich nun folgendes Festgestellt:
    Im folgenden Tutorial werden z.B. für Menüpunkte (wxMenu und wxMenuBar) schon Pointer verwendet:
    http://zetcode.com/tutorials/wxwidgetstutorial/menustoolbars/
    Daher auch meine Annahme, das man mit Pointern arbeiten soll! (Wa ja anscheinend falsch war)

    Gibt es eine Regel, wann Pointer und wann nicht (z.B. für wxTextCtrl, wxStaticText, wxPanel, etc)


  • Mod

    stefanjann schrieb:

    OK, nun hab ich die Pointer raus und siehe da: Es geht tatsächlich. (*newbee-Verwunderung*)

    Gibt es eine Regel, wann Pointer und wann nicht (z.B. für wxTextCtrl, wxStaticText, wxPanel, etc)

    Hm, jein.

    Bei wxWidgets gilt, das man alle Fenster mit new erstellen muss, also auch Menus etc., da wxWidgets sich hier selber um die Speicherverwalter der Fenster kümmert. Zum Teil wird dass dann auch in der Dokumentation erwähnt.

    Generell empfiehlt sich ein Pointer, wenn man z.B. eine andere Lebenszeit des Objektes hat, als die des "haltenden" Objektes, z.b. ein Socket.
    Oder wenn ein Objekt nicht zwingend vorhanden sein muss, wie z.B. eine Verbindung, ein Childfenster oder Observer.

    phlox



  • Das ist doch schon mal ein guter Anhaltspunkt.
    Danke schön.


Anmelden zum Antworten