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

l2m*_*2m2 3 c++ lambda c++11

在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;
Run Code Online (Sandbox Code Playgroud)

输出是:

15
5772973
2686617
2686617
Run Code Online (Sandbox Code Playgroud)

这背后的原因是什么?

Rak*_*111 7

因为未定义的行为.

tmpf1分配后被破坏,因此tmp_p变成悬垂指针.当你取消引用它时,任何事情都可能发生,包括有时给出正确的价值15,有时则没有5772973.

同样适用f2,但不使用指针,而是使用引用,引用被破坏的对象,这也是未定义的行为.


Adr*_*ski 5

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

第一种情况:f1():这导致了它,因为调用这些lambda表达式的值之后int tmp,并int *tmp_p没有在堆栈上了(在int *tmp_p被复制,但int tmp被移除).

第二种情况:: 通过引用内部lambda访问f2()tmp.生成lambda完成后,它不再在堆栈上了,有些东西获得了内存并写入了垃圾.