How to delete QTcpSocket properly



  • Hello.
    I'm getting 'access violation' error while using this code:

    Project file:

    QT       += core gui network
    
    greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
    
    TARGET = TcpSocketTest
    TEMPLATE = app
    
    
    SOURCES += main.cpp\
            mainwindow.cpp
    
    HEADERS  += mainwindow.h
    

    main.cpp:

    #include "mainwindow.h"
    #include <QApplication>
    
    int main(int argc, char *argv[])
    {
        QApplication a(argc, argv);
        MainWindow w;
        w.show();
    
        return a.exec();
    }
    

    mainwindow.h:

    #ifndef MAINWINDOW_H
    #define MAINWINDOW_H
    
    #include <QWidget>
    #include <QPushButton>
    #include <QHBoxLayout>
    #include <QTcpSocket>
    
    class MainWindow : public QWidget
    {
        Q_OBJECT
    public:
        MainWindow(QWidget* parent = 0);
    private slots:
        void onClicked();
        void onConnected();
    private:
        QPushButton* btn = nullptr;
        QTcpSocket* socket = nullptr;
    };
    
    #endif // MAINWINDOW_H
    

    mainwindow.cpp:

    #include "mainwindow.h"
    
    MainWindow::MainWindow(QWidget *parent)
        : QWidget(parent)
    {
        setFixedWidth(320);
        setWindowTitle("TCP connection test");
    
        setLayout(new QHBoxLayout);
        btn = new QPushButton("Start test");
        connect(btn, &QPushButton::clicked, this, &MainWindow::onClicked);
        layout()->addWidget(btn);
    }
    
    void MainWindow::onClicked()
    {
        btn->setEnabled(false);
    
        // I want to instantiate QTcpSocket on the heap
        Q_ASSERT(socket == nullptr);
        socket = new QTcpSocket(this);
    
        Q_ASSERT(connect(socket, &QTcpSocket::connected, this, &MainWindow::onConnected));
        socket->connectToHost("google.com", 80, QIODevice::ReadWrite);
    }
    
    void MainWindow::onConnected()
    {
        Q_ASSERT(socket != nullptr);
    
        // I want to delete QTcpSocket as soon as I don't need it.
        delete socket;
        socket = nullptr;
    
        btn->setEnabled(true);
    }
    

    Please help me fix it.

    Environment: Windows 8.1 x64, Qt 5.4.1.


  • Lifetime Qt Champion

    Hi,

    Use socket->deleteLater() That will schedule the object delete through the even loop so that any pending events for the object will be removed from the event queue and it can be safely deleted.



  • @SGaist Got it. So I changed onConnected function:

    void MainWindow::onConnected()
    {
        Q_ASSERT(socket != nullptr);
    
        socket->disconnect();
        socket->disconnectFromHost();
        socket->deleteLater();
        // Don't need to delete it manually
        // because parent will delete it automatically
        socket = nullptr;
    
        btn->setEnabled(true);
    }
    

    Is it looks good now?



  • @YuriQ Well, I think it is.


  • Lifetime Qt Champion

    The code is good but the comment is false, it's not the parent that will delete socket, it's the event loop at the next occasion.


Log in to reply
 

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