QThread ASSERT failure in QMutexLocker: “QMutex pointer is misaligned”,

隐身守侯 提交于 2019-12-02 04:12:50

QThread::start() is what actually starts the thread (as a different thread). QThread::run() is just a regular function, so if you call it without calling start() first, you're executing it in the main thread.

The funny thing about it is that your derived class was created in the main thread, so it "belongs" in the main thread. I'm guessing you're giving your class as the parent to something else; this is what is generating the error message when you try to do this after calling start(). Can you leave those objects parent-less?

You won't be able to create gui objects in another thread, Qt just doesn't allow it (yet?). But other objects can be created, you just can't give them a parent in a different thread.

The error you are receiving

ASSERT failure in QMutexLocker: "QMutex pointer is misaligned"

occurs on creation of a QMutexLocker object if the QMutex object passed to the constructor is not aligned on a 2-byte boundary in RAM (in Qt 4.7.1 at least).

The QMutexLocker object uses one member variable to represent both the location of the mutex in memory and its state (whether it is locked or not). The state is represented by the least significant bit of the variable, while the least significant bit of the mutex pointer is assumed to be zero. If this bit is not zero, the ASSERT exception above is thrown.

The only reason for misalignment of the QMutex pointer I can think of is a memory leak or corruption. Check whether you destroy all memory that you allocate (especially in loops) and check all typecasts (you might have casted a pointer of a smaller type to a pointer of a bigger type, damaging memory) and null-terminated strings (which will damage memory if not properly terminated). Finally, verify the thread safety of all memory that you share across threads.

This is probably because the order some object in your application is created. I would recommend inherit from QObject instead of QThread, and move the object to a worker thread instead (QObject::moveToThread()). Also move any code that is initialized in FileUploader to a separate slot in FileUploader, say init(). Invoke init (QMetaObject::invokeMethod()) when the thread is running (after calling start on the worker thread). E.g.:

FileUploader : public QOject
{
...
public slots:
void init() { Foo *foo = new Foo(this); }
}

// main thread
QThread worker;
FileUploader *fup = new FileUploader();
fup->moveToThread(&worker);
worker.start();
QMetaObject::invokeMethod(fup, "init", Qt::QueuedConnection); 
//
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!