1

I have the following function that is called each time a user click a button :

void Foo::onCommand1Clicked(int index)
{
    connect(this, &Foo::authorized, this, [=]() {

        // avoid multiple connections 
        QObject::disconnect(this, &Foo::authorized, this, nullptr);

        // do work based on "index" captured by value ( or other parameters in real code )
        this->processCommand1(index);
        
        // ..

       
        }
    });
}

Now, if the command is "authorized" ( the signal is asynchronously emitted but may also not be emitted at all), then the lambda containing the command logic is executed. Moreover, while the command is pending for authorization, the button is disabled ( preventing the function to be called )

My question is about the lambda connected to the signal and especially its parameters captured by value : Are those parameters eventually released from memory or do they accumulate into the memory stack each time the connection is done (ie the button is clicked) ?

More generally, is there any kind of "memory leak" or "continuously growing stack" in this code ?

Thank you.

Fryz
  • 2,119
  • 2
  • 25
  • 45
  • 2
    A capturing lambda is like a functor - a struct with member variables and an overloaded `operator()()`. If the signal handler lambda is disconnected the struct instance is deleted with all its member variables. – Scheff's Cat Jul 07 '20 at 10:44
  • FYI: [SO: What is a lambda expression in C++11?](https://stackoverflow.com/a/7627218/7478597) – Scheff's Cat Jul 07 '20 at 10:49

1 Answers1

0

for lambda connections in Qt third parameter called context is used. In your case is this pointer. So, while this is alive, connection is active. When you create a lambda connection, lambda object is moved as a whole object to connection manager. When you disconnect from your signal, lambda object should be dead (as i suggest). Maybe it's deleted later. So I reccomend to insert disconnect as last instruction in lambda. However, this is still alive. A also recommend you to use another mechanism to call async task, than connecting/disconnecting to a signal in the same object! A thread, for instance. Or to call QTimer::singleShot. I don't see in what circumstances authorized signal is emitted

Pie_Jesu
  • 1,894
  • 3
  • 16
  • 30
  • Thanks for your answer. the `authorized` signal is indeed emitted from another thread. – Fryz Jul 07 '20 at 16:30
  • How could it be? It's clear, that `this` object emits the signal. How could happen `this` emits signal from another thread, while also `this` object calls the slot in current thread? A `QObject` can't belong to many threads at a single moment – Pie_Jesu Jul 07 '20 at 16:36
  • Actually, the signal is emitted from a callback function - that is a member of Foo - and this callback is executed in another thread. – Fryz Jul 07 '20 at 16:38