Trismegistos
Trismegistos

Reputation: 3882

Why this pointer captured by lambda is corrupted while other variable is not

I have compiled (g++ -std=c++11 a.cpp) and run following code:

#include <iostream>
#include <functional>

using namespace std;

class A {
    std::function<void(void)> f;
public:
    A(std::function<void(void)> pf) : f(pf) {}
    void callf() { f(); }
};

class B {
    A *a;
public:
    void test() {
        B *that = this;
        auto f = [this, that]() {
            cout << "this: " << this << " that: " << that << endl;
            delete this->a;
            cout << "this: " << this << " that: " << that << endl;
        };

        a = new A(f);
        a->callf();
    }
};

int main()
{
    B().test();
}

Its output was:

this: 0x7fff158c88f0 that: 0x7fff158c88f0
this: 0x1ea3000 that: 0x7fff158c88f0

I do not understand why captured this changed its value while identical pointer with different name was not corrupted.

Edit:

I understand that lambda is destroyed and I am producing UB but what I do not understand is why one variable is corrupted while other not. I do not understand low level details behind this behaviour which is by the way very consistent. I want to understand gcc implementation details that cause this kind of behaviour.

My further investigation showed that changing auto f = [this, that] to auto f = [that, this] caused that to be corrupted.

Upvotes: 1

Views: 962

Answers (2)

Pradhan
Pradhan

Reputation: 16777

You are calling delete this->a; and this->a is what holds f, leading to UB.

Upvotes: 1

Lightness Races in Orbit
Lightness Races in Orbit

Reputation: 385325

Undefined behaviour, innit. You just destroyed the lambda you're executing.

Upvotes: 6

Related Questions