Reputation: 207
I have a code like:
#include <cstdio>
#include <functional>
class test {
public:
void Do() {
this->test_fun();
}
void Init() {
this->number = 1008;
this->test_fun = [this] {
this->test_fun = nullptr;
printf("number %d\n", this->number); //gcc crash here, this == nullptr
};
}
public:
std::function<void()> test_fun;
int number = 0;
};
int main() {
test t;
t.Init();
t.Do();
return 0;
}
It can run on MSVC2013, but crash on gcc on the line: printf("number %d\n", this->number);
What am I doing wrong?
GCC Version: gcc version 4.8.2 20140120 (Red Hat 4.8.2-15) (GCC)
Upvotes: 3
Views: 136
Reputation:
Your code introduces undefined behavior, due to the the self destruction of the lambda with
this->test_fun = nullptr;
This example should be equivalent:
#include <cstdio>
#include <cassert>
#include <memory>
class test {
public:
struct Lambda {
test* this_ptr;
Lambda(test* this_ptr) : this_ptr(this_ptr) {}
~Lambda() {
this_ptr = nullptr;
}
void operator () () {
printf("this_ptr %p\n", (void*)this_ptr);
// self destruction
this_ptr->test_fun = nullptr;
// undefined behavior starts here ...
printf("this_ptr %p\n", (void*)this_ptr);
printf("number %d\n", this_ptr->number);
}
};
void Do() {
assert(this->test_fun.get());
(*this->test_fun)();
}
void Init() {
this->number = 1008;
this->test_fun = std::make_unique<Lambda>(this);
}
public:
std::unique_ptr<Lambda> test_fun;
int number = 0;
};
int main() {
test t;
t.Init();
t.Do();
return 0;
}
Upvotes: 3