Seite 1 von 1

[gelöst] Speicherzugriffsfehler bei Signals und Slots

Verfasst: 11. November 2007 14:57
von boer
Hallo zusammen,

ich bekomme aufgrund einer QObject::connection einen Speicherzugriffsfehler, wenn ich das Programm ausführen möchte. Dabei verbinde ich ein Signal der Klasse StartMenue mit einem Slot der Klasse CoordWindow.
Das Programm besteht aus zwei Menüs. Das StartMenue wird beim Starten des Programms aufgerufen. Hier kann man die IP Adresse des Servers, Port, usw. angeben. Wenn man auf den Connect-Button klickt wird eine Verbindung zum spezifizierten Server aufgebaut (Funktioniert problemlos, die Daten des Servers kann ich auf der Konsole ausgeben). Daraufhin öffnet sich ein zweites Menü (CoordWindow), das die empfangenen Daten darstellen soll.
Hier mal die relevanten Ausschnitte des Quellcodes:

Code: Alles auswählen

//--startmenue.h ----------------------------
//Die Klasse Startmenue ist eine einfache GUI, die es ermöglicht ein par Konfigurationen vorzunehmen und eine Verbindung mit einem Server herstellen kann(via TCP Socket)

class StartMenue : public QWidget
{
  Q_OBJECT

public:
  StartMenue(QWidget *parent = 0);

private slots:
  void showCoord();

// ...

signals:
  void coordsChanged(float newValue);

private:
  float myValue;    //Wert, der vom Server empfangen wird und in CoordWindow dargestellt werden soll
  CoordWindow *coordWindow;   //weiteres Menü, dass Daten von Server darstelt

//...

};

Code: Alles auswählen

//--startmenue.cpp ----------------------------

StartMenue::StartMenue(QWidget *parent) : QWidget(parent)
{
  //...

  connect(connectButton, SIGNAL(clicked()), this, SLOT(showCoord()));
  connect(this, SIGNAL(coordsChanged(float), coordWindow, SLOT(setData(float)));   // <----- das ist die 'Problem'-connection <------

  //...

}

//...

void StartMenue::showCoord()
{
  coordWindow = new CoordWindow(this);
  coordWindow->show();
}

//...

//das ist ein Privater Slot, der die Daten des Socket Servers liefert
void StartMenue::getResponse()
{

  //...

  myValue = 1.1;   //einfa testhalber ein Float deklariert, myValue ist ein private-Attribut, siehe Klassendefinition.
  emit coordsChanged(myValue);
  
  //...

}

Code: Alles auswählen

//--coordwindow.h ----------------------------

//...

class CoordWindow : public QWidget
{
  Q_OBJECT

public:
  CoordWindow(QWidget *parent = 0);

public slots:
  void setData(float newValue);

private:
  float coordValue;

//...

};

Code: Alles auswählen

//--coordwindow.cpp ----------------------------

//...

void CoordWindow::setData(float newValue)
{
  coordValue = newValue;
  xled1ValueLabel->setText(QString::number(coordValue); //der Float Wert soll einfach in einem QLabel dargestellt werden
}
Kann hier jemand einen Fehler erkennen? Ich hab schon einiges ausprobiert, komme aber leider nicht darauf, warum ein Speicherzugriffsfehler eintritt. wenn ich die connection entferne funktioniert das Programm einwandfrei.

Danke schon mal!

Verfasst: 11. November 2007 15:22
von Burgpflanze
coordWindow ist zu diesem Zeitpunkt noch nicht instanziert.

Verfasst: 11. November 2007 15:44
von boer
Hallo Peter,

danke für deine schnelle Antwort.

CoordWindow ist zu diesem zeitpunkt schon instanziiert, das geht aus den Code-Schnippseln vielleicht nicht hervor, aber CoordWindow wird beim Klick auf den Connect-Button Instanziiert. Des weiteren wird beim Klick auf den connect-Button die Verbindung aufgebaut (SIGNAL: connectToServer(), hier nicht im Beispiel enthalten). Die Float-Variable wird übergeben, nachdem die Verbindung aufgebaut wurde und das signal readyRead() von TCPSocket emitiert wurde, d.h. wenn Daten im Empfangspuffer vorhanden sind. Zu diesem Zeitpunkt ist das Menü CoordWindow bereits vorhanden.

Ich habe aber gerade nochetwas ausprobiert:
Ich ab als Float-Variable nicht das private Attribut myValue dem Signal übergeben, sondern eine lokal erstellt Variable

Code: Alles auswählen

 float myFloat = 1.1; 
, funktioniert aber trotzdem nicht.

Verfasst: 11. November 2007 16:04
von boer
Hallo Peter,

Tschuldigung für meine voreilige Antwort, du hattest natürlich recht!
Hab nur bischen gebraucht, bis ich dich richtig verstanden hab.

Ich hab jetzt in den Konstruktor von StartMenue folgendes geschrieben:

Code: Alles auswählen

 
coordWindow = new CoordWindow(this);
coordWindow->hide();
Im slot StartMenue::showCoord() hab ich die erste Zeile dann gelöscht und evola, kein Speicherzugriffsfehler mehr.

Vielen Dank!!