1

当使用 GCC (4.7.2-5ubuntu) 而不是 Clang (Apple LLVM 4.2) 编译时,此代码会在运行时生成 SIGSEGV

#include <functional>
#include <iostream>

using FuncType = std::function<int(int)>;

int func(FuncType f, int i) {
    return f(i)+1;
}

struct Alpha {
    FuncType f, g;
    Alpha(FuncType f) : f(f) {
        g = [&](int i) -> int {
            return func(f, i);
        };
    }
    int go(int i) {
        return g(i);
    }
};

struct Beta {
    int k = 0;
    Beta newBeta(int nk) {
        Beta beta = *this;
        beta.k = nk;
        return beta;
    }
};

struct Gamma {
    Beta beta;
    void go(int j) {
        auto f = [&](int i) -> int {
            int n = beta.newBeta(i).k+j;
            return n*n;
        };
        Alpha alpha(f);
        std::cout << alpha.go(beta.k) << std::endl;
    }
};

int main(int argc, char *argv[]) {
    Gamma gamma;
    gamma.go(7);
    return 0;
}

f调试中,在调用lambda 时会发生崩溃funcbeta报告为无效对象,即使在调用 lambda 时它应该仍然有效。

看起来这是这个错误的结果,但据报道该错误已在 4.7.2 中修复。

编辑:为清楚起见进行了初始化Beta::k,不影响错误。

4

1 回答 1

4

这里有一个问题:

Alpha(FuncType f) : f(f) {
    g = [&](int i) -> int {
        return func(f, i);
    };
}

您的 lambda 通过引用绑定f(构造函数的参数,因此构造函数的本地参数),因此在构造函数完成后,该引用悬空。当您稍后调用 时g,您会得到未定义的行为,因为它引用了这个悬空引用。

将 to更改为[&][=]值绑定,应该没问题。

于 2013-02-13T17:25:12.587 回答