Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

'this' pointer changes in c++11 lambda

I found a very strange problem with this pointer in c++11's lambda.

#include <string>
#include <iostream>
using namespace std;

#include <boost/signals2.hpp>

boost::signals2::signal<void()> sig;

struct out {
    void print_something() {
        cout << "something" << endl;
    }
    out() {
        auto start = [&] {
            cout << "this in start: " << this << endl;
            this->print_something();
        };

        cout << "this in constructor: " << this << endl;

        // sig.connect(start);
        sig.connect([&] {
            cout << "this in signal: " << this << endl;
            start();
        });
        this->print_something();
    }
};

int main() {
    out o;
    sig();
}

The code prints three this(s) pointer at different location. I was expecting that all the three this pointer should be the same value, but they are not. Here's the output:

this in constructor: 00F3FABB
something
this in signal: 00F3FABB
this in start: 00F3FB00
something

Question 1: Why is this in start has different value? How to correct it?

Question 2: Since the this in start is a different pointer, it shouldn't be able to call print_something(). I would expect a crash on this but it works fine. Why?

like image 361
aj3423 Avatar asked Jun 19 '16 12:06

aj3423


1 Answers

You capture start by reference, but the variable start and the contained lambda function get destroyed at the end of out().

Later the signal handler tries to call start(), but the lambda function doesn't exist anymore. Maybe the memory where its this was stored was overwritten in the mean time, causing unexpected output.

The call to print_something() doesn't crash despite of the invalid this because the function doesn't actually try to use this. The printing in the function is independent of this and the lookup of print_somethings address can happen at compile time so that calling the function doesn't access this at runtime.

like image 87
sth Avatar answered Jan 02 '23 11:01

sth