3

After learning lambda in C++11, I wrote this and got confused by the output.

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;

Output is:

15
5772973
2686617
2686617

What's the reason behind this?

2
  • 3
    But they return lambdas with parameters and are executed immediately Commented Sep 1, 2016 at 9:42
  • @AdrianJałoszewski sorry just noticed Commented Sep 1, 2016 at 9:44

2 Answers 2

7

Because undefined behavior.

tmp gets destructed after f1 is assigned, and so tmp_p becomes a dangling pointer. Anything can happen when you dereference it, including sometimes given the right value 15, and sometimes not 5772973.

The same goes for f2, but instead of using a pointer, you use a reference, which references a destructed object, which is also undefined behavior.

Sign up to request clarification or add additional context in comments.

Comments

5

This is what we call undefined behavior. Why is your code causing undefined behavior?

First case: f1(): It's causing it, because after calling these lambdas the values of int tmp and int *tmp_p aren't on the stack anymore (the int *tmp_p was copied but the int tmp was removed).

Second case: f2(): The value of tmp was accessed by reference to the inner lambda. After the generating lambda finished it wasn't on the stack anymore and something obtained the memory and wrote garbage into it.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.