此代码在使用GCC(4.7.2-5ubuntu)但不是Clang(Apple LLVM 4.2)编译时在运行时生成SIGSEGV
#include <functional>
#include <iostream>
using FuncType = std::function<int(int)>;
int func(FuncType f, int i) {
return f(i)+1;
}
struct Alpha {
FuncType f, g;
Alpha(FuncType f) : f(f) {
g = [&](int i) -> int {
return func(f, i);
};
}
int go(int i) {
return g(i);
}
};
struct Beta {
int k = 0;
Beta newBeta(int nk) {
Beta beta = *this;
beta.k = nk;
return beta;
}
};
struct Gamma {
Beta beta;
void go(int j) {
auto f = [&](int i) -> int {
int n = beta.newBeta(i).k+j;
return n*n;
};
Alpha alpha(f);
std::cout << alpha.go(beta.k) << std::endl;
}
};
int main(int argc, char *argv[]) {
Gamma gamma;
gamma.go(7);
return 0;
}
调试,在f
中调用lambda func
时发生崩溃。 beta
报告为无效对象,即使在调用lambda时它仍然有效。
看起来这是this bug的结果,但据报道该错误已在4.7.2中修复。
修改:为了清晰起见,已初始化Beta::k
,不会影响错误。
答案 0 :(得分:4)
这里有一个问题:
Alpha(FuncType f) : f(f) {
g = [&](int i) -> int {
return func(f, i);
};
}
你的lambda通过引用绑定f
(构造函数的参数和构造函数的本地参数),因此在构造函数完成之后,该引用是悬空的。当您稍后调用g
时,您会得到未定义的行为,因为它引用了这个悬空引用。
将[&]
更改为[=]
以按值绑定,它应该没问题。