Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. deleteLater as a slot causes Access Vialoation
QtWS25 Last Chance

deleteLater as a slot causes Access Vialoation

Scheduled Pinned Locked Moved Solved General and Desktop
5 Posts 4 Posters 1.3k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • jronaldJ Offline
    jronaldJ Offline
    jronald
    wrote on last edited by jronald
    #1
    
    void StockIDUpdateTask::run()
    {
        QUrl url("http://www.test.com");
        networkReply = networkAccessManager.get(QNetworkRequest(url));
        connect(networkReply, &QNetworkReply::finished, this, &MyThread::WebPageDownloadSucceeded);
        connect(networkReply, &QNetworkReply::finished, networkReply, &QNetworkReply::deleteLater);
        exec();
    }
    
    void MyThread::WebPageDownloadSucceeded()
    {
        QByteArray ba = networkReply->readAll();
        return;
    }
    

    Here connect a signal to two slots, Doesn't they executed one by one? Why does it cause access violation? If the 2nd connect is commented out, then no access violation.

    BTW, if call networkReply->deleteLater() in MyThread::WebPageDownloadSucceeded(), networkReply need to be a member of the class, not so cute.

    raven-worxR 1 Reply Last reply
    0
    • hskoglundH Offline
      hskoglundH Offline
      hskoglund
      wrote on last edited by
      #2

      Hi, you can try rewriting your WebPageDownloadSucceeded() function so that it accepts one argument (the networkReply), say like this:

      void StockIDUpdateTask::run()
      {
          QUrl url("http://www.test.com");
          networkReply = networkAccessManager.get(QNetworkRequest(url));
          connect(networkReply, &QNetworkReply::finished, this, &MyThread::WebPageDownloadSucceeded);
          exec();
      }
      
      void MyThread::WebPageDownloadSucceeded(QNetworkReply* networkReply)
      {
          QByteArray ba = networkReply->readAll();
          networkReply->deleteLater();
      }
      

      That way you can call deleteLater() without crashes.

      1 Reply Last reply
      0
      • jronaldJ jronald
        
        void StockIDUpdateTask::run()
        {
            QUrl url("http://www.test.com");
            networkReply = networkAccessManager.get(QNetworkRequest(url));
            connect(networkReply, &QNetworkReply::finished, this, &MyThread::WebPageDownloadSucceeded);
            connect(networkReply, &QNetworkReply::finished, networkReply, &QNetworkReply::deleteLater);
            exec();
        }
        
        void MyThread::WebPageDownloadSucceeded()
        {
            QByteArray ba = networkReply->readAll();
            return;
        }
        

        Here connect a signal to two slots, Doesn't they executed one by one? Why does it cause access violation? If the 2nd connect is commented out, then no access violation.

        BTW, if call networkReply->deleteLater() in MyThread::WebPageDownloadSucceeded(), networkReply need to be a member of the class, not so cute.

        raven-worxR Offline
        raven-worxR Offline
        raven-worx
        Moderators
        wrote on last edited by
        #3

        @jronald said in deleteLater as a slot causes Access Vialoation:
        why don't you simply call deleteLater() when you know you've read all data in the first place?

        I guess the issue is that in the first case the signal is "transmitted" via the even-loop (queued connection) to the other thread. Thus it is not guaranteed to be processed before the deleteLater() in the same thread (where the QNetworkReply lives in).

        --- SUPPORT REQUESTS VIA CHAT WILL BE IGNORED ---
        If you have a question please use the forum so others can benefit from the solution in the future

        hskoglundH 1 Reply Last reply
        1
        • raven-worxR raven-worx

          @jronald said in deleteLater as a slot causes Access Vialoation:
          why don't you simply call deleteLater() when you know you've read all data in the first place?

          I guess the issue is that in the first case the signal is "transmitted" via the even-loop (queued connection) to the other thread. Thus it is not guaranteed to be processed before the deleteLater() in the same thread (where the QNetworkReply lives in).

          hskoglundH Offline
          hskoglundH Offline
          hskoglund
          wrote on last edited by hskoglund
          #4

          @raven-worx good point, so another possible solution could be:

          ...
          connect(networkReply, &QNetworkReply::finished, this, &MyThread::WebPageDownloadSucceeded,Qt::BlockingQueuedConnection);
          connect(networkReply, &QNetworkReply::finished, networkReply, &QNetworkReply::deleteLater);
          ...
          
          1 Reply Last reply
          1
          • VRoninV Offline
            VRoninV Offline
            VRonin
            wrote on last edited by VRonin
            #5

            I don't really agree with the users before me (which normally means I'm wrong 😉 ). This is a fundamental design flaw.

            QThread is not the thread, it's a wrapper around it.

            Things created inside run() are on the secondary thread but thing created in the QThread constructor and the QThread itself are in the main thread.

            This means networkReply = networkAccessManager.get(QNetworkRequest(url)); is a race condition and even calling networkReply->deleteLater(); from WebPageDownloadSucceeded would be (but probably deleteLater is smart enough to avoid it)

            The segfault comes from the fact that deleteLater is direct connection (receiver and sender are the same so by definition they are on the same thread) while WebPageDownloadSucceeded is queued connected as networkReply lives in the secondary thread while this lives in the main thread.

            Please see https://mayaposch.wordpress.com/2011/11/01/how-to-really-truly-use-qthreads-the-full-explanation/ and refactor your code to apply that tutorial

            "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
            ~Napoleon Bonaparte

            On a crusade to banish setIndexWidget() from the holy land of Qt

            1 Reply Last reply
            1

            • Login

            • Login or register to search.
            • First post
              Last post
            0
            • Categories
            • Recent
            • Tags
            • Popular
            • Users
            • Groups
            • Search
            • Get Qt Extensions
            • Unsolved