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?
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_something
s address can happen at compile time so that calling the function doesn't access this
at runtime.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With