Solved workerThread.wait() gives heap corruption errors
-
Hello,
I am getting the following errors when exiting my Qt program in Debug mode:
HEAP[Logger.exe]: Invalid address specified to RtlValidateHeap( 00E50000, 00AF5460 )
Debug Assertion Failed!Program: ...ogger-Desktop_Qt_5_14_0_MSVC2017_32bit-Debug\debug\Logger.exe
File: minkernel\crts\ucrt\src\appcrt\heap\debug_heap.cpp
Line: 904Expression: _CrtIsValidHeapPointer(block)
For information on how your program can cause an assertion
failure, see the Visual C++ documentation on asserts.(Press Retry to debug the application)
Debug Assertion Failed!If I click "Retry", I get many more errors including one about heap corruption. Where am I going wrong?
Here is my code:
MainWindow.hclass MainWindow : public QMainWindow
{
Q_OBJECT
QThread workerThread;
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
void theEnd();public slots:
void newEntry();private:
Ui::MainWindow *ui;
Logging &logger = Logging::getInstance();signals:
void doStuff(QtMsgType Type = QtInfoMsg, const QString *Msg = nullptr, const char *File = nullptr, int Line = 0);
};MainWindow.cpp
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);connect(ui->pushButton, &QPushButton::clicked, this, &MainWindow::newEntry); logger.moveToThread(&workerThread); workerThread.start(); connect(&workerThread, &QThread::finished, &logger, &QObject::deleteLater); connect(this, &MainWindow::doStuff, &logger, &Logging::newLogEntry); connect(&logger, &Logging::finished, this, &MainWindow::theEnd);
}
MainWindow::~MainWindow()
{
workerThread.quit();
workerThread.wait(); // THIS LINE IS GIVING THE ERRORS
delete ui;
}void MainWindow::newEntry()
{
std::cout << "Main Window: " << std::this_thread::get_id() << std::endl;
QString *msg = new QString("Slot message");
emit doStuff(QtCriticalMsg, msg, FILE, LINE);
}void MainWindow::theEnd()
{}
Logging.h
class Logging : public QObject
{
Q_OBJECT
public:
~Logging();
struct LoggingInfomation { QtMsgType type; QByteArray localMsg; const char *file; int line; };
friend QDataStream &operator<<(QDataStream &out, const Logging::LoggingInfomation &logger);
static Logging& getInstance();public slots:
void connected();
void disconnected();
void bytesWritten(qint64 bytes);
void readyRead();
void newLogEntry( QtMsgType Type = QtInfoMsg, const QString *Msg = nullptr, const char *File = nullptr, int Line = 0);signals:
void finished();private:
explicit Logging(QObject *parent = nullptr);
QTcpSocket *socket;
LoggingInfomation logger;
QMutex mutex;Logging.cpp
Logging::Logging(QObject *parent)
{
parent = nullptr;
socket = new QTcpSocket(this);connect(socket, &QAbstractSocket::connected, this, &Logging::connected); connect(socket, &QAbstractSocket::disconnected, this, &Logging::disconnected); connect(socket, &QAbstractSocket::bytesWritten, this, &Logging::bytesWritten); connect(socket, &QAbstractSocket::readyRead, this, &Logging::readyRead);
}
Logging::~Logging()
{}
Logging& Logging::getInstance()
{
static Logging instance;return instance;
}
void Logging::newLogEntry(QtMsgType Type, const QString *Msg, const char *File, int Line)
{
mutex.lock();std::cout << "Logger: " << std::this_thread::get_id() << std::endl;
logger.type = Type;
logger.localMsg = Msg->toUtf8();
logger.file = File;
logger.line = Line;socket->connectToHost("127.0.0.1", 80);
socket->waitForConnected(1000);mutex.unlock();
}void Logging::connected()
{
std::cout << "Connected!" << std::endl;
QByteArray string;
QDataStream stream(&string, QIODevice::ReadWrite);
stream.setVersion(QDataStream::Qt_5_14);
stream << logger;
socket->write(string);
socket->flush();socket->waitForBytesWritten(1000); socket->disconnectFromHost();
}
void Logging::disconnected()
{
std::cout << "Disconnected!" << std::endl;
}void Logging::bytesWritten(qint64 bytes)
{
std::cout << "We wrote: " << bytes << " bytes" << std::endl;
emit finished();
}void Logging::readyRead()
{
std::cout << "Reading..." << std::endl;
qInfo() << socket->readAll();
}QDataStream &operator<<(QDataStream &out, const Logging::LoggingInfomation &logger)
{
out << logger.file << logger.type << logger.localMsg << logger.line;
return out;
}I am using the Logging class as a singleton.
-
@itanitarek10
In yourconnect()
it is notworkerThread
which is getting deleted! It islogger
. -
@itanitarek10 said in workerThread.wait() gives heap corruption errors:
connect(&workerThread, &QThread::finished, &logger, &QObject::deleteLater);
You try to delete an object which is not a pointer.
-
@Christian-Ehrlicher said in workerThread.wait() gives heap corruption errors:
@itanitarek10 said in workerThread.wait() gives heap corruption errors:
connect(&workerThread, &QThread::finished, &logger, &QObject::deleteLater);
You try to delete an object which is not a pointer.
I'll try making workerThread a pointer to a new QThread object.Edit: Misunderstood what @Christian-Ehrlicher pointed out.
-
@itanitarek10
In yourconnect()
it is notworkerThread
which is getting deleted! It islogger
. -
@JonB issue would be the same. Stack objects are automatically deleted.
-
@JonB said in workerThread.wait() gives heap corruption errors:
@itanitarek10
In yourconnect()
it is notworkerThread
which is getting deleted! It islogger
.I changed
connect(&workerThread, &QThread::finished, &logger, &QObject::deleteLater);
to be
connect(&workerThread, &QThread::finished, &workerThread, &QObject::deleteLater);
and the problem went away! Thanks for your help!
-
@JonB issue would be the same. Stack objects are automatically deleted.
I don't understand? @Christian-Ehrlicher is pointing out:
You try to delete an object which is not a pointer.
which I agree with. OP says he is looking at
workerThread
inconnect(&workerThread, &QThread::finished, &logger, &QObject::deleteLater);
. I'm saying what's wrong is he is trying to deletelogger
. Are you saying anything different? Isn't this the cause of the OP's heap pointer issue? -
@itanitarek10 said in workerThread.wait() gives heap corruption errors:
connect(&workerThread, &QThread::finished, &workerThread, &QObject::deleteLater);
What do you expect from this connect at all?
And no I did not tell you to change it this way...