0

我正在尝试构建一个包含一些输入函数和一些前/后操作的 lambda。

  • 如果我尝试包装常规函数/lambda,我的代码可以正常工作,并且可以正确调用前/后操作。
  • 但是,当我尝试将装饰 lambda 应用于它之前生成的函数时,我的程序在抱怨内部函数在某个时候被释放后崩溃(这已由 valgrind 确认)。

Xcode 6 clang令我困惑的是,崩溃取决于编译器:代码在( based)下工作得很好clang-3.6,但在 linux 上使用clang++-3.6and崩溃g++4.8.4

我制作了一个重现行为的小程序:

#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()
}

我在变量范围管理中做错了什么?该程序是否有任何理由使用 Apple 的 LLVM 崩溃?

编辑

作为记录,这里是TClambdaFactory建议更正后的正确:

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

1 回答 1

2

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

该程序是否有任何理由不使用 Apple 的 LLVM 崩溃?

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

于 2015-06-25T10:13:35.407 回答