在下面的代码中,我认为p2应该打印10。但实际上它打印的是随机值。我开始理解为什么它不是 10,有以下 (1)-(3) 想法。
{
int m = 10; // local var m
qDebug() << "m0: " << &m;
connect(btn2, &QPushButton::clicked, this, [&]() { qDebug() << "m2: " << &m; qDebug() << "p2 " << m; m = 20; qDebug() << "p22 " << m; }); // captured var m
}
Run Code Online (Sandbox Code Playgroud)
输出:
m0: 0x8ff8ac
p0 10
m2: 0x8ff8ac
p2 11974204
p22 20
m2: 0x8ff8ac
p2 20
p22 20
Run Code Online (Sandbox Code Playgroud)
(1). 第一次调用 lambda 时,其捕获的 varm具有随机值。我认为这可能是因为 local varm是一个局部变量,并且它位于堆栈内存中,在 后释放},此后它是随机的。
(2)。在lambda内部将capturedm分配为20后,当第二次调用时,m仍然是20。这与我在(1)中的想法相反,因为当退出lambda函数时,m应该释放内存,然后再次随机值。
(3)。[&]使 lambda 能够访问已释放的内存,这不是很危险吗?
根据我的上述想法,我的问题是为什么捕获的 m 不是 10(p2打印什么)?为什么释放的内存可以被访问和修改,这不是很危险吗?为什么 lambda 的第二次访问m不是随机的?
因为你通过引用捕获它。
一旦函数结束,其所有局部变量的生命周期也结束。局部变量不再存在。任何对它们的引用或指针都将变得无效。使用此类引用或取消引用此类指针将导致未定义的行为。
通过引用捕获的所有变量的生命周期必须至少与 lambda 本身的生命周期一样长。