Bus error! Element zu Liste hinzufuegen



  • Hallo Forum,

    nun, es ist es wieder einmal soweit - ich muss euch um eure Hilfe bitten!
    Und zwar bin ich gerade dabei mich in C++ einzuarbeiten. Ich bin dabei mit QT4 ein kleines Chat-Programm zu schreiben und habe dabei schwierigkeiten.
    (Auch wenn ich das Programm mit QT schreibe poste ich hier, weil ich der Ueberzeugung bin, dass das Problem nichts mit QT zu tun hat - vielmehr liegt es wahrscheinlich an mir)
    Folgende Klasse macht Probleme:

    #include <QtCore>
    #include <QtNetwork>
    #include <QList>
    #include <iostream>
    #include "Client.h"
    
    class ClientList : public QObject
    {
    	Q_OBJECT 
    
    	public:
    		ClientList();
    
    		void registerUser( QString* name, QHostAddress* host );
    		void unregisterUser( QHostAddress* host );
    		void updateUser( QString* name, QHostAddress* host ); 
    
    	private:
    		bool clientAlreadyExists( const QHostAddress* host );
    
    		QList<Client*>* clientList;
    };
    
    #endif
    
    #include "ClientList.h"
    
    ClientList::ClientList()
    {
    	clientList = new QList<Client*>;
    };
    
    void 
    ClientList::registerUser( QString* name, QHostAddress* host )
    {
    	if ( !clientAlreadyExists( host) )
    	{
    		std::cout << "Add: " << host->toString().toStdString() << std::endl;
    		Client* client = new Client( name, host );
    		clientList->append( client );
    	} 
    	else
    		std::cout << "already exists" << std::endl; 
    };
    
    void 
    ClientList::unregisterUser( QHostAddress* host )
    {
    };
    
    void 
    ClientList::updateUser( QString* name, QHostAddress* host )
    {
    };
    
    bool 
    ClientList::clientAlreadyExists( const QHostAddress* host )
    {
    	return false;
    };
    

    Und zwar liegt das Problem beim hinzufuegen vom Client zur Liste! Nun, ich koennte mir vorstellen, dass das daran liegt, dass ich den Client in der Methode definiere und dann hinzufuege.
    Wenn ja, wie kann ich das Problem umgehen?

    Oder liege ich da ganz falsch?
    🙄 bitte um Rat!!!

    mfg



  • moe szyslak schrieb:

    Und zwar liegt das Problem beim hinzufuegen vom Client zur Liste!

    Kurze Zwischenfrage: Wie äußert sich denn dein Problem?



  • Im Absturz des Programms.
    Das Programm startet zuerst einen UDP-Server, sendet eine Broadcast anfrage ins Netz, erhaelt die Antwort und versucht dann die somit erhaltenen Werte in die ClientList einzutragen.
    Das geschieht ueber eine weitere Klasse, dem Controller.

    Sobald die GUI-Elemente aufgebaut sind erhalte ich noch die folgende Nachricht:

    Add: 127.0.0.1
    Bus error

    und crash.

    Ein paar Zeilen Crash-Report?

    Date/Time: 2005-12-19 15:12:27.788 +0100
    OS Version: 10.4.3 (Build 8F46)
    Report Version: 3

    Command: m4u-gui
    Path: ./m4u-gui.app/Contents/MacOS/m4u-gui
    Parent: bash [218]

    Version: ??? (???)

    PID: 6338
    Thread: 0

    Exception: EXC_BAD_ACCESS (0x0001)
    Codes: KERN_PROTECTION_FAILURE (0x0002) at 0x00000000

    Thread 0 Crashed:
    0 m4u-gui 0x0000b30c QList<Client*>::detach() + 28 (qlist.h:94)
    1 m4u-gui 0x0000b368 QList<Client*>::append(Client* const&) + 36 (qlist.h:392)
    2 m4u-gui 0x00005410 ClientList::registerUser(QString*, QHostAddress*) + 336 (ClientList.cpp:30)
    3 m4u-gui 0x000059f8 Controller::registerUser(QString*, QHostAddress*) + 56 (Controller.cpp:51)
    4 m4u-gui 0x000068e4 UdpServer::udpReceiver() + 392 (UdpServer.cpp:65)
    5 m4u-gui 0x00008b18 UdpServer::qt_metacall(QMetaObject::Call, int, void**) + 128 (moc_UdpServer.cpp:66)
    6 QtCore 0x02078bcc QMetaObject::activate(QObject*, int, void**) + 888 (icplusplus.c:28)
    7 QtNetwork 0x005b1950 QAbstractSocketPrivate::canReadNotification(int) + 344 (icplusplus.c:28)
    8 QtNetwork 0x005b21a8 QAbstractSocket::qt_metacall(QMetaObject::Call, int, void**) + 440 (icplusplus.c:28)
    9 QtCore 0x02078bcc QMetaObject::activate(QObject*, int, void**) + 888 (icplusplus.c:28)
    10 QtCore 0x0208e99c QSocketNotifier::activated(int) + 72 (icplusplus.c:28)
    ...

    Beim Kompilieren erhalte ich keine Fehlermeldungen, ausser den Paar Variablen, die ich noch nicht benutze.

    mfg

    P.S.: Vielleicht noch wichtig, der Client erbt von QObject.



  • Kannst du denn mit dem Debugger reinsehen, wie sich die Werte während der Abarbeitung verändern?

    (btw, eventuell liegt das Problem auch irgendwo in der Client-Klasse)



  • Ich habs mal mit gdb versucht:

    Program received signal EXC_BAD_ACCESS, Could not access memory.
    Reason: KERN_PROTECTION_FAILURE at address: 0x00000008
    0x000053fc in ClientList::registerUser (this=0x0, name=0xbfffde6c, host=0xbfffde64) at ClientList.cpp:30
    30 clientList->append( client );

    Versteh aber nicht ganz was das soll ...

    An der ClientKlasse liegt es glaub ich nicht, sie macht doch eigentlich gar nichts.

    #include "Client.h"
    
    Client::Client( QString* name, QHostAddress* host ) :
    	userName( name ), hostAddress( host )
    {
    };
    
    Client::~Client()
    {
    	delete userName;
    	delete hostAddress;
    };
    
    void 
    Client::updateName( QString* name )
    {
    	userName = name;
    };
    
    void 
    Client::updateAddress( QHostAddress* host )
    {
    	hostAddress = host;
    };
    
    const QHostAddress* 
    Client::getHostAddress() const
    {
    	return hostAddress;
    };
    


  • Stimmt, die macht nichts - und das ist womöglich zu wenig. Wenn du mit dynamischen Komponenten arbeitest, solltest du zumindest einen Copy-Ctor und Zuweisungsoperator bereitstellen, sonst löscht dir irgendein temporäres Objekt innerhalb der QList::Append() deine Ursprungsdaten.



  • Das kann sein.
    Im Moment stell ich das ganze Zeug von Pointern auf Referenzen um, was ja klappt.
    Aber irgendwie schaff ich es nicht das = zu ueberlagern.

    Client& 
    Client::operator= ( const Client& client )
    {
    //	Client cl( userName, hostAddress );
    
    	Client* cl = new Client( userName, hostAddress );
    
    	return *cl;
    };
    

    Naja, gut - ich mach da mal spaeter weiter.
    Brauch erst mal ne Pause, vielen Dank fuer die geleistete Hilfe und
    fuer jeden weiteren Tipp!

    mfg



  • im operator= bringt es herzlich wenig, ein neues Objekt anzulegen, das sofort wieder gelöscht wird - du mußt die Elemente von this entsprechend anpassen:

    Client& Client::operator=(const Client& other)
    {
      if(this!=&other) //Schutz vor Selbstzuweisung
      {
        //alte Werte löschen
        delete userName;
        delete hostAdress;
        //neu zuweisen
        userName=new QString(other.userName);
        hostAdress=new QHostAdress(other.hostAdress);
      }
      return *this;
    }
    


  • Sorry, das Problem mit dem Objekt hab ich schon selbst geloest.
    Das war halt mein erster Versuch ueberhaupt einen Operator zu ueberlagern und da hat man halt manchmal anlaufschwierigkeiten bis man eine gute Erklaerung im www dazu findet!

    Ich glaube dass das Problem daran liegt, dass die Elemente zur Liste ueber eine slot-Funktion hinzugefuegt werden, etwa in der Art:
    UdpServer->register
    Controller->register
    ClientList->siehe oben


Anmelden zum Antworten