Speicherzugriffsfehler bei Zugriff auf Klassen_Element



  • Hallo,

    Es handelt sich um eine QT-Applikation , allerdings ist das Problem wohl eher ein generelles...

    ich habe im Designer ein Widget erzeugt und in dem ui.h eine von QTable abgeleitete Tabelle eingefügt.

    das kompilieren läuft soweit durch, doch irgendwas scheint nicht zu passen, da wenn ich aus dem Widget auf die Tabelle zugreife, dann gibt es einen Speicherzugriffsfehler.

    Ich schätze mal, dass ich auf das falsche Objekt zugreife.
    Aber warum ?

    Wer kann mir da einen Tipp geben ?

    vielen Dank im Voraus,

    Needle

    Code:

    // form1.ui.h
    
    #include <qtable.h>
    #include <qobject.h>
    
    #include "mytable.h"
    
    myTable *Tabelle;
    
    void Form1::init()
    {
    	myTable *Tabelle = new myTable(this);
    	Tabelle->setGeometry(10,40,400,400);
    	Tabelle->setNumRows(5);
    	Tabelle->setNumCols(5);
    	return;
    }
    
    void Form1::doSlot()
    {
    	for ( int x =0 ; x < 4 ; x++)
    	{
    		for (int y = 0 ; y < 4 ; y++)
    		{
    			Tabelle->setText( x,y, "FILLED");
    		}
    	}
    	return;
    }
    

    ein Buttondruck springt zurr Laufzeit doSlot() an und es wird auf die Tabelle zugegriffen.
    genau dann gibts es den Speicherzugriffsfehler... 😞

    // mytable.h
    #ifndef MYTABLE_H
    #define MYTABLE_H
    
    #include <qtable.h>
    
    class myTable : public QTable 
    {
    	Q_OBJECT
    public:
    	myTable ( QWidget * parent = 0 , const char * name = 0 );
    	~myTable ();
    };
    #endif
    
    // mytable.cpp
    #include "mytable.h"
    
    myTable::myTable(QWidget *parent, const char *name)
    		: QTable ( parent , name )
    {
    };
    
    myTable::~myTable()
    {
    };
    


  • Relativ einfach: in der init-Methode erstellst Du einen lokalen Zeiger. Der wird zerstört wenn die Funktion zuende ist. Der globale Zeiger wird in der init-Methode nie angetastet.



  • LordJaxom schrieb:

    Relativ einfach: in der init-Methode erstellst Du einen lokalen Zeiger. Der wird zerstört wenn die Funktion zuende ist. Der globale Zeiger wird in der init-Methode nie angetastet.

    versteht ich net, aber ich würde den pointer mal wieder mit delete löschen?

    edit: okay, ich vergas -> wird automatisch in QT gelöscht ^^

    mfg blan



  • @blan:

    int Tabelle; // globale Variable
    
    void init(void)
    {
      int Tabelle; // lokale Variable
      /* ... */
    } // lokale Variable weg
    

    Verstanden?

    Ach, und nicht löschen ist zwar nicht schön, aber führt auch nicht zum Crash.



  • LordJaxom schrieb:

    @blan:

    int Tabelle; // globale Variable
    
    void init(void)
    {
      int Tabelle; // lokale Variable
      /* ... */
    } // lokale Variable weg
    

    Verstanden?

    Ach, und nicht löschen ist zwar nicht schön, aber führt auch nicht zum Crash.

    achso - wow ganz übersehn... jo hab mein beitrag scho editiert, weil QT die teile eh automatisch löscht..

    mfg blan



  • LordJaxom schrieb:

    @blan:

    int Tabelle; // globale Variable
    
    void init(void)
    {
      int Tabelle; // lokale Variable
      /* ... */
    } // lokale Variable weg
    

    Verstanden?

    Ach, und nicht löschen ist zwar nicht schön, aber führt auch nicht zum Crash.

    soweit ja klar...

    nur wenn ich dann in einer Funktion auf die globale Tabelle zugreifen will klappt das auch nicht.

    wenn ich das so mache crashed das Teil auch :

    void Form1::init()
    {
        //myTable *Tabelle = new myTable(this);
        Tabelle->setGeometry(10,40,400,400);
        Tabelle->setNumRows(5);
        Tabelle->setNumCols(5);
        return;
    }
    


  • ja du must schon ein myTabelle = new myTable(this) reinbauenen, du greifst grad auf ein nicht vorhandenes object zu. dein pointer myTabelle greif auf irgendeine stelle im speicher zu -> du nbekommst sicher einen segmentation fault?

    mfg blan



  • Nunja, vorher hast Du Dir Dein Objekt in eine lokale Variable erzeugt, die am Ende der Funktion verloren ging. Jetzt erzeugst Du das Objekt gleich garnicht mehr 😉



  • blan schrieb:

    ja du must schon ein myTabelle = new myTable(this) reinbauenen, du greifst grad auf ein nicht vorhandenes object zu. dein pointer myTabelle greif auf irgendeine stelle im speicher zu -> du nbekommst sicher einen segmentation fault?

    mfg blan

    ok - das problem ist ja folgendes:

    die form1 ist eine widgetklasse, die vom QT-Designer (Visueller Oberflaechendesigner)erzeugt wird.
    das ::init() ist nur eine funktion, die nach(!) durchlauf des Konstruktors von form1 durchlaufen wird.

    warscheinlich ist es dann doch ein recht QT-spezifisches Problem.



  • need_input schrieb:

    blan schrieb:

    ja du must schon ein myTabelle = new myTable(this) reinbauenen, du greifst grad auf ein nicht vorhandenes object zu. dein pointer myTabelle greif auf irgendeine stelle im speicher zu -> du nbekommst sicher einen segmentation fault?

    mfg blan

    ok - das problem ist ja folgendes:

    die form1 ist eine widgetklasse, die vom QT-Designer (Visueller Oberflaechendesigner)erzeugt wird.
    das ::init() ist nur eine funktion, die nach(!) durchlauf des Konstruktors von form1 durchlaufen wird.

    warscheinlich ist es dann doch ein recht QT-spezifisches Problem.

    naja du kannst aufjedenfall nicht auf ein object zugreifen, dass nicht existiert - hast du den code schonmal so verändert wie ich gesagt hab?

    mfg blan



  • Statt diesem hier:
    [cpp]
    myTable *Tabelle;

    void Form1::init()
    {
    *myTable Tabelle = new myTable(this); //hier wird ein lokaler Zeiger "myTable" angelegt der genauso heist wie der globale. Der lokale Zeiger hat gegenüber dem globalen in der Fkt Vorrang
    Tabelle->setGeometry(10,40,400,400);
    Tabelle->setNumRows(5);
    Tabelle->setNumCols(5);
    return;
    }
    [/cpp]

    solltest du das hier machen

    myTable *Tabelle;
    
    void Form1::init()
    {
        Tabelle = new myTable(this);
        Tabelle->setGeometry(10,40,400,400);
        Tabelle->setNumRows(5);
        Tabelle->setNumCols(5);
        return;
    }
    


  • need_input:
    Dein Problem hat in dem Fall garnix mit QT zu tun. Wenn ich auf ein Objekt zugreife, welches nicht initialisiert ist (der Variablen wurde nichts zugewiesen) dürfte es bei jedem anderen Framework auch krachen.

    Bei Deinem ersten Versuch hattest Du eine globale Variable Tabelle. Dann in der Methode init eine lokale Variable Tabelle. Dieser lokalen Variable weist Du ein neues Objekt zu und machst was damit. Dann ist init zuende und die lokale Variable weg. Später greifst Du also auf die globale Variable zu, der nie etwas zugewiesen wurde.

    Bei Deinem zweiten Versuch hast Du die lokale Variable ganz eliminiert, und benutzt stattdessen die un-initialisierte globale Variable Tabelle.

    Der goldene Mittelweg wäre, die lokale Variable wegzulassen aber der globalen ein neues Objekt (mit new) zuzuweisen 😉

    @Chris++: Nope, sorry, das Sternchen stört noch...



  • need_input schrieb:

    void Form1::init()
    {
        //myTable *Tabelle = new myTable(this);
        Tabelle->setGeometry(10,40,400,400);
        Tabelle->setNumRows(5);
        Tabelle->setNumCols(5);
        return;
    }
    

    Ganz klar - du hast etwas zu viel auskommentiert. Der Teil "Tabelle = new myTable(this);" ist noch notwendig, um die Tabelle anzulegen.



  • blan schrieb:

    need_input schrieb:

    blan schrieb:

    ja du must schon ein myTabelle = new myTable(this) reinbauenen, du greifst grad auf ein nicht vorhandenes object zu. dein pointer myTabelle greif auf irgendeine stelle im speicher zu -> du nbekommst sicher einen segmentation fault?

    mfg blan

    ok - das problem ist ja folgendes:

    die form1 ist eine widgetklasse, die vom QT-Designer (Visueller Oberflaechendesigner)erzeugt wird.
    das ::init() ist nur eine funktion, die nach(!) durchlauf des Konstruktors von form1 durchlaufen wird.

    warscheinlich ist es dann doch ein recht QT-spezifisches Problem.

    naja du kannst aufjedenfall nicht auf ein object zugreifen, dass nicht existiert - hast du den code schonmal so verändert wie ich gesagt hab?

    mfg blan

    ich habe mir jetzt mal genau den designer angesehen und nachgelesen wie das gui-klassendesign dort funktioniert. (ok - haette ich mal vorher drauf kommen koennen... sorry) jetzt habe ich das Tabellen-Objekt wie es sich gehört in der Gui-Klasse angegeben und kann jetzt problemlos drauf zugreifen.

    ist halt ne QT-Designer-spezifische Vorgehensweise - wer mehr Info zur Lösung möchte -> melden.

    Danke euch,

    Need_Input


Anmelden zum Antworten