变量在调用lambda之前被销毁

Variable getting destroyed before calling lambda

本文关键字:调用 lambda 变量      更新时间:2023-10-16

我正在尝试构建一个lambda,它用一些前/后操作包装一些输入函数。

  • 如果我试图包装一个正则函数lambda,我的代码运行良好,并且可以正确地调用前/后操作
  • 然而,当我试图将装饰lambda应用于它之前生成的函数时,我的程序在抱怨内部函数在某个时刻被释放后崩溃(valgrind证实了这一点)

让我困惑的是,崩溃取决于编译器:代码在Xcode 6 clang(基于clang-3.6)上运行得很好,但在使用clang++-3.6g++4.8.4的linux上崩溃。

我制作了一个再现这种行为的小程序:

#include <iostream>
#include <string>
#include <functional>
using namespace std;
typedef function<void(void)> NestedFn;
int main()
{
    // Create a cfunction
    auto lambdaFactory = [&](string title, NestedFn nestedFunc)
    {
        // title is copied to the new lambda
        return [&, title]() {
            cerr << "------------ START -----------" << endl;
            cerr << "Inside: " << title << endl;
            nestedFunc();
            cerr << "------------- END ------------" << endl;
        };
    }
    auto l1 = lambdaFactory("1", []() { cerr << "tNest (1)" << endl; });
    auto l2 = lambdaFactory("2", []() { cerr << "tNest (2)" << endl; });
    l1(); // Works ok, displays, START, 1, END
    l2(); // Same here
    auto dobble = lambdaFactory("Dobble", l1);
    dobble(); // Display START, Inside Dobble, START, 
              // then crashes when trying to execute nestedFunc(), ie l1()
}

我在可变范围管理中做错了什么?这个程序没有使用苹果的LLVM崩溃有什么原因吗?

编辑

为了记录,这是T.C.建议校正后的正确lambdaFactory

auto lambdaFactory = [&](string title, NestedFn nestedFunc)
{
  return [&, title, nestedFunc]() {
        cerr << "------------ START -----------" << endl;
        cerr << "Inside: " << title << endl;
        nestedFunc();
        cerr << "------------- END ------------" << endl;
    };
};

lambdaFactory的调用返回的lambda通过引用捕获nestedFunc,但nestedFunc是一个通过值传递的函数参数,因此一旦对lambdaFactory的调用返回,它就会超出范围,从而导致悬空引用。

这个程序没有使用苹果的LLVM崩溃,有什么原因吗?

未定义的行为是未定义的。您还可能使用两种不同的标准库实现(Mac上的libc++/linux上的libstdc++),因此在布局等方面可能存在差异。