Molin.L
Molin.L

Reputation: 113

When does a variable copy be released in lambda function?

As the example below, I define 2 variables x and y. When I call the lambda function twice, it seems like it will not destroy the copy. From 11.14 — Lambda captures | Learn C++ - Learn C++, it says:

Because captured variables are members of the lambda object, their values are persisted across multiple calls to the lambda!

How does C++ manage the memory for lambda function?

int main() {
    int x = 1;
    static int y = 1;
    auto fun = [=]() mutable{
        x++;
        y++;
        cout<<"Inside:\t\t";
        cout<<"x:"<<x<<"\t"<<"y:"<<y<<endl;
    };

    for (int i = 0; i<2; i++) {
        fun();
        cout<<"Outside:\t";
        cout<<"x:"<<x<<"\t"<<"y:"<<y<<endl<<endl;
    }
}

Output:

Inside:         x:2     y:2
Outside:        x:1     y:2

Inside:         x:3     y:3
Outside:        x:1     y:3

Upvotes: 1

Views: 356

Answers (1)

Kevin Anderson
Kevin Anderson

Reputation: 7010

It stores it inside the object itself. Another way to think of your lambda is below. This is "kind of" equivalent to what the compiler is generating, and yes, I'm changing scopes around a bit and I know that, but this may be clearer to a beginner at C++.

static int y = 1; // Moved this out from main
class my_lambda{
public:
my_lambda(int x) : _x(x) {}
~my_lambda() = default;
void operator()()
{
  _x++;
  y++;
  cout<<"Inside:\t\t";
  cout<<"_x:"<<_x<<"\t"<<"y:"<<y<<endl;
}

private:
int _x;
};

int main() {
    int x = 1;
    my_lambda fun{x}; // "Captures" x

    for (int i = 0; i<2; i++) {
        fun();
        cout<<"Outside:\t";
        cout<<"x:"<<x<<"\t"<<"y:"<<y<<endl<<endl;
    }
}

As you can hopefully see, the "fake lambda" class I made is doing the same thing your actual lambda is. It "captures" x as part of its constructor and copies it to internal storage, which I called _x. And y is just in scope for it, though I moved to global to be above the class declaration.

I'm overloading the () operator to make a class that's callable, which is a normal thing to do in some circumstances. See operator overloading if you wish for more information.

So this is "kind of, sorta" how lambdas work. They take your body and put it into the operator() of the object that's generated, and anything captured is one of the object's variables, with either the actual object (if by value) or a reference, if captured that way.

And to directly answer your question: when fun goes out of scope, it is freed, both in a lambda, and my case.

Upvotes: 2

Related Questions