Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

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: 904

    Expression: _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.h

    class 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 your connect() it is not workerThread which is getting deleted! It is logger.


  • Lifetime Qt Champion

    @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 your connect() it is not workerThread which is getting deleted! It is logger.


  • Lifetime Qt Champion

    @JonB issue would be the same. Stack objects are automatically deleted.



  • @JonB said in workerThread.wait() gives heap corruption errors:

    @itanitarek10
    In your connect() it is not workerThread which is getting deleted! It is logger.

    @Christian-Ehrlicher

    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!



  • @SGaist

    @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 in connect(&workerThread, &QThread::finished, &logger, &QObject::deleteLater);. I'm saying what's wrong is he is trying to delete logger. Are you saying anything different? Isn't this the cause of the OP's heap pointer issue?


  • Lifetime Qt Champion

    @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...


Log in to reply