捕获临时变量引用的Lambda传入另一函数后,访问原变量是否合法?
问题分析:Lambda捕获形参引用的生命周期问题
先看你给出的代码(补上原代码遗漏的分号):
void func(const int temp) { auto lambda_func = [&temp]() { return std::make_unique<int>(temp); }; return another_func(lambda_func); }
核心结论分两种情况:
- 如果
another_func在func函数还没返回的时候就调用lambda_func,那完全没问题,能正常访问temp的值; - 如果
another_func把lambda_func保存起来(比如存到全局变量、堆对象里),等func执行完返回后再调用,那就是未定义行为。
原因解释
temp是func的函数形参,它的生命周期和func的栈帧绑定——只要func还在执行,栈帧没销毁,temp就一直存在。lambda按引用捕获的是temp的内存地址,当func执行完毕返回时,栈帧会被销毁,temp占用的内存会被释放(或被后续栈操作覆盖),此时lambda里的引用就变成了悬空引用。
一旦出现悬空引用,再通过lambda访问temp的行为就是未定义的:可能拿到随机垃圾值,可能直接导致程序崩溃,甚至可能出现看似正常但逻辑完全错误的结果——C++标准不会对这种行为做任何保证。
举个例子:
- 安全场景:
another_func直接调用lambda,此时func栈帧仍存在,temp有效:void another_func(std::function<std::unique_ptr<int>()> func) { auto ptr = func(); // 调用lambda时temp还活着,无问题 // 处理ptr... } - 危险场景:
another_func保存lambda,后续异步调用时temp已销毁:std::function<std::unique_ptr<int>()> global_func; void another_func(std::function<std::unique_ptr<int>()> func) { global_func = func; // 保存lambda } // 等func返回后,在其他地方调用 global_func(); // 此时temp已销毁,访问temp属于未定义行为
内容的提问来源于stack exchange,提问作者24n8
相关产品推荐
相关产品推荐

