Emitting signals from unrelated file causes break



  • I am attempting to emit multiple of the same signal in one function. Is this not possible, or am I doing it wrong?
    Function with Emitting:

    void mydialog::testfunction(int t, int b)
    {
    	emit testsignal("Hello, World!");
    	Sleep(2000);
    	qDebug("Number: %d/%d", t, b);
    	Sleep(10000);
    	emit testsignal("Hello, World2!");
    }
    

    Calling it

    	QtConcurrent::run(this, &mydialog::testfunction, 9, 8);
    

    Error thrown after the second emit (12 Seconds Later)

    Exception thrown at 0x000000005391BFEE (Qt5Core.dll) in legit.exe: 0xC0000005: Access violation reading location 0x0000000000000023. occurred
    

    If anymore info is needed then please ask.



  • My first bet would be that the instance of mydialog gets deleted/out-of-scope while the signal still must be delivered. But I'm not sure, I need to see some more code then.



  • This post is deleted!


  • This post is deleted!


  • @bludger With more testing and moving my tests to a new project I think i've come up with a more narrow scenario so you can help me easier. I've now switch from emitting from a closing dialog to emitting from an unrelated file, yet I still hit breakpoints during the emit, but this time even if I emit once.
    emittertest.h

    #include <QObject>
    
    class emittertest : public QObject
    {
    	Q_OBJECT
    public:
    	void fnc(QString r);
    signals:
    	void fnctest(QString);
    private:
    	int value;
    };
    

    emittertest.cpp

    #include "emittertest.h"
    #include "qdebug.h"
    #include <windows.h>
    void emittertest::fnc(QString t)
    {
    	qDebug() << t << "Thanks";
    	//emit fnctest("Word");
    	emit fnctest(QString("Rio"));
    }
    

    My app's .cpp file

    void gq(QString Rex)
    {
    	while (true) {
    		qDebug() << "Name:" << Rex << "Thread:" << QThread::currentThread();
    		Sleep(2000);
    	}
    }
    void QtTestApp::myslot(QString t)
    {
    	qDebug() << "Signal Emitted: " << t;
    }
    QtTestApp::QtTestApp(QWidget *parent)
    	: QMainWindow(parent)
    {
    	ui.setupUi(this);
    	emittertest b;
    	connect(&b, SIGNAL(fnctest(QString)), this, SLOT(myslot(QString)));
    	QFuture<void> f2 = QtConcurrent::run(&b, &emittertest::fnc, QString("NAME"));
    
    }
    

    Error

    Exception thrown at 0x0000000063DFCE09 (Qt5Cored.dll) in QtTestApp.exe: 0xC0000005: Access violation reading location 0x000001FA8800F021. occurred
    
    


  • The emittertest variable gets out of scope before the signal is emitted. Upon connect you use the address of b so Qt's metasystem uses that address until the signal and slot are being disconnected. When leaving the constructor all local variables are going out-of-scope and so does b, meaning that the address of b became invalid.
    A quick fix would be moving the local variable b to be a class member variable. Or making it a pointer instead so the object lives on the heap (make sure you delete it properly to avoid any memory leaks).

    class QtTestApp : public QMainWindow
    {
       Q_OBJECT
    ....
    private:
       emittertest m_b;
    }
    

    Or as a pointer: (also a class member)

    class QtTestApp : public QMainWindow
    {
       Q_OBJECT
    ...
    private:
       emittertest* m_b;
    }
    


  • @bludger Trying it your way and I get these errors

    Severity	Code	Description	Project	File	Line	Suppression State
    Error	C2065	'm_b': undeclared identifier	QtTestApp	C:\Users\Contempt\source\repos\QtTestApp\QtTestApp\QtTestApp.cpp	21	
    
    Severity	Code	Description	Project	File	Line	Suppression State
    Error	C4430	missing type specifier - int assumed. Note: C++ does not support default-int	QtTestApp	c:\users\contempt\source\repos\qttestapp\qttestapp\QtTestApp.h	15	
    
    Severity	Code	Description	Project	File	Line	Suppression State
    Error	C3646	'm_b': unknown override specifier	QtTestApp	c:\users\contempt\source\repos\qttestapp\qttestapp\QtTestApp.h	15	
    
    
    

    My QtTestApp.h

    class QtTestApp : public QMainWindow
    {
    	Q_OBJECT
    
    public:
    	QtTestApp(QWidget *parent = Q_NULLPTR);
    	private slots:
    	void myslot(QString);
    private:
    	emittertest m_b;
    	Ui::QtTestAppClass ui;
    };
    

    And I can not run emittertest::fnc() in a QtConcurrent thread anymore.



  • It's still a race condition as there is nothing stopping your QMainWindow destroying before QtConcurrent::run finished. There is a way of making it work even with QtConcurrent but it's harder than just using QThread: see https://mayaposch.wordpress.com/2011/11/01/how-to-really-truly-use-qthreads-the-full-explanation/



  • @Contempt I guess you forgot to include the emittertest header file in QtTestApp.h. As long as it is not known within the QtTestApp header you will get the errors you're reporting.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.