我有一个代码:
#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;
}
它可以在MSVC2013上运行,但在行上的gcc崩溃:printf("number %d\n", this->number);
我做错了什么?
海湾合作委员会版本:gcc版本4.8.2 20140120(红帽4.8.2-15)(GCC)
答案 0 :(得分:3)
您的代码引入了未定义的行为,因为lambda的自毁已经
this->test_fun = nullptr;
这个例子应该是等价的:
#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;
}