Lambda按值捕获参数包后调用崩溃,求正确原理解析
调用Lambda触发SIGSEGV的原因解析
问题核心
崩溃的根本原因不是参数包的捕获逻辑,而是你对op的引用捕获导致了悬空引用。
详细分析
- 在
wrapper函数中,op是函数的形参,存储在栈帧上。当你用[&op, args...]定义lambda时,lambda保存的是op的引用,而非op本身的副本。 - 当
wrapper函数执行完毕返回lambda后,wrapper的栈帧会被销毁,形参op占用的内存被释放,变成无效内存区域。 - 回到
main函数调用f()时,lambda尝试通过引用访问已经失效的op,此时访问的是非法内存,直接触发段错误(SIGSEGV)。
修复方案
将op的捕获方式从引用改为值捕获,让lambda保存op的副本,这样即使wrapper的栈帧销毁,副本依然有效。修复后的代码如下:
#include <iostream> using namespace std; void argPrinter(double d, int v, bool b) { cout << "argPrinter: " << " " << d << " " << v << " " << b << endl; } template <typename Callable, typename... Args> auto wrapper(Callable op, Args&&... args) { auto result = [op, args...] () mutable { // 按值捕获op cout << "Hello\n"; op(args...); }; return result; } int main() { auto f = wrapper(argPrinter, 28.7, -99, true); f(); // 正常执行,输出预期内容 }
补充说明
你之前担心的参数包args...捕获是没问题的,args...确实是按值捕获的,这部分不会导致崩溃。问题完全出在对op的引用捕获上。
内容的提问来源于stack exchange,提问作者Rajat
相关产品推荐
相关产品推荐

