在这种情况下被lambda输出混淆

时间:2016-09-01 09:39:21

标签: c++ c++11 lambda

在C ++ 11中学习lambda之后,我写了这个并且对输出感到困惑。

auto f1 = [] () {
    int tmp = 10;
    int *tmp_p = &tmp;
    return [tmp_p] (int x) {
        return *tmp_p + x;
    };
}();

auto f2 = []() {
    int tmp = 10;
    return [&tmp] (int x) {
        return tmp + x;
    };
}();

cout << f1(5) << endl;
cout << f1(5) << endl;

cout << f2(5) << endl;
cout << f2(5) << endl;

输出是:

15
5772973
2686617
2686617

这背后的原因是什么?

2 个答案:

答案 0 :(得分:7)

因为未定义的行为。

分配tmp

f1被破坏,因此tmp_p成为悬空指针。当您取消引用它时,任何事情都可能发生,包括有时给出正确的值15,有时不是5772973

同样适用于f2,但您使用的引用代替使用指针,引用了被破坏的对象,这也是未定义的行为。

答案 1 :(得分:5)

这就是我们所说的undefined behavior。为什么您的代码导致未定义的行为?

第一种情况:f1(): 它导致了它,因为在调用这些lambda之后,int tmpint *tmp_p的值不再在堆栈中(int *tmp_p被复制但int tmp被删除了)。

第二种情况:f2():通过引用内部lambda来访问tmp的值。在生成lambda之后,它不再存在于堆栈中,并且某些东西获得了内存并将垃圾写入其中。